How should I obtain an appropriate boolean result? - python-3.x

I've written some code and here's a short bit
x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print('apple' in x)
how do I get this statement as true, since apple already exists in x, I still keep getting the False as the boolean value.

When the in operator is applied to a list like you have here it looks for an exact match in the list. Your code is returning false because 'apple' isn't in the list, 'apple, iphone' is. To check each element in the list for the substring 'apple' you could use list comprehension. Something like:
x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print(True in ['apple' in s for s in x])
What the second line does is use list comprehension to build a list of booleans indicating if the substring 'apple' is in that element. Then it checks if True is in the resulting list.
or instead of using the in operator:
x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print(any(['apple' in s for s in x]))
The any built-in function returns true if any element in an iterable is True.

x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print(True in ('apple' in d for d in x))

Maybe use a function like this:
IsItemInList(item, list):
for x in list:
if x == item:
return True
return False
Pretty sure theres a much cleaner way to do this but that was my first guess. As we know, the first is mostly the worst.

Related

What is 'x' behind the 'if' in the 2nd row mean?

str_list = ["Emma", "Jon", "", "Kelly", None, "Eric", ""]
str_list = [x for x in str_list if x]
print(str_list)
Python supports the concepts of "truthy," meaning a value treated as logically true, and "falsey," a value logically treated as false. As it turns out, empty string is falsey, so the if x condition in the list comprehension will exclude empty string values.
Here, checking if x is implicitly looking at bool(x). Specifically, notice that when x is an empty string, bool(x) is false: we say that it is "falsy." You can see this for yourself interactively:
>>> bool("Emma")
True
>>> bool("")
False
>>>
This list comprehension effectively filters out these "falsy" values, or in this case, empty strings.
For more about common truth values and how to customize your own, see the Python docs.

Finding a substring in a jumbled string

I am writing a script - includes(word1, word2) - that takes two strings as arguments, and finds if word1 is included in word2. Word2 is a letter jumble. It should return Boolean. Also repetition of letters are allowed, I am only checking if the letters are included in the both words in the same order.
>>>includes('queen', 'qwertyuytresdftyuiokn')
True
'queen', 'QwertyUytrEsdftyuiokN'
I tried turning each word into lists so that it is easier to work with each element. My code is this:
def includes(w1, w2):
w1 = list(w1)
w2 = list(w2)
result = False
for i in w1:
if i in w2:
result = True
else:
result = False
return result
But the problem is that I need to also check if the letters of word1 comes in the same order in word2, and my code doesn't controls that. I couldn't find a way to implement that with list. Just like I couldn't do this much with strings, so I think I need to use another data structure like dictionary but I don't know much about them.
I hope I understood what is your goal.
Python is not my thing, but I think I made it pythonic:
def is_subsequence(pattern, items_to_use):
items_to_use = (x for x in items_to_use)
return all(any(x == y for y in items_to_use) for x, _ in itertools.groupby(pattern))
https://ideone.com/Saz984
Explanation:
itertools.groupby transfers pattern in such way that constitutive duplicates are discarded
all items form form grouped pattern must fulfill conditions
any uses generator items_to_use as long as it doesn't matches current item. Note that items_to_use mus be defined outside of final expression so progress on it is kept every time next item from pattern is verified.
If you are not just checking substrings:
def include(a, b):
a = "".join(set(a)) # removes duplicates
if len(a) == 1:
if a in b:
return True
else:
return False
else:
try:
pos = b.index(a[0])
return include(a[1:], b[pos:])
except:
return False
print(include('queen', 'qwertyuytresdftyuiokn'))
#True

Mark Element in List

I have an excercise about prime numbers that requires me to write a function which takes a list of elements and a number p and marks elements False which are in the range 2p, 3p...N
First I create a list of True and False:
true_value = [False, False] + [True for x in range(n-1)] #Let assumme that n=16
And then I write the function that find the even number in this list (with p = 2)
def mark_false(bool_list, p):
range_new = [x for x in range(len(bool_list))]
for i in range(2, len(range_new)):
for j in range(p, len(range_new), p):
if (i*p == range_new[j]) & (i*p <= len(range_new)):
bool_list[j] = False
return bool_list
This function help me to find the location of the even number (>2) and return to False
Example: a = list_true(16)
a = [False,False,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True]
b = mark_false(a, 2)
b = [False,False,True,True,False,True,False,True,False,True,False,True,False,True,False,True]
This function mark_false does work but the problem is everytime I run it I have to create a list range_new which takes a lot of time to calculate. So how do I rewrite this function so it can run faster without creating new lists?
You seem to be doing things the long way around, searching for the j value that matches the multiple of p you want to set to False. But since you already know that value already, there's no need to search for it, just set it directly.
I'd do:
def mark_false(bool_list, p):
for i in range(p, len(bool_list), p): # p, 2*p, 3*p, ...
bool_list[i] = False # do the assignment unconditionally
You probably shouldn't need a return statement, since you're modifying the list you are passed in-place. Returning the list could make the API misleading, as it might suggest that the returned list is a new one (e.g. a modified copy).
If you did want to return a new list, you could create one with a list comprehension, rather than modifying the existing list:
def mark_false_copy(bool_list, p):
return [x if i % p else False for i, x in enumerate(bool_list)]

Python 3.X: Implement returnGreater() function using a list of integers and a value

The function must return a list consisting of the numbers greater than the second number in the function
It must be able to do the following when functioning:
returnGreater([1,2,3,4,5], 3)
[4,5]
returnGreater([-8,2,-4,1,3,-5],3)
[]
Here's what I have (I've gone through a few iterations), though I get a Type Error for trying to use a ">" symbol between an int and list:
def returnGreater (x,y):
"x:list(int) , return:list(int)"
#greater: int
greater = []
for y in x:
#x: int
if x > y:
x = greater
return greater
You're using the name y for two different things in your code. It's both an argument (the number to compare against) and the loop variable. You should use a different name for one of those.
I'd strongly suggest picking meaningful names, as that will make it much clearer what each variable means, as well as making it much less likely you'll use the same name for two different things. For instance, here's how I'd name the variables (getting rid of both x and y):
def returnGreater(list_of_numbers, threshold):
greater = []
for item in list_of_numbers:
if item > threshold:
greater.append(item)
return greater
You had another issue with the line x = greater, which didn't do anything useful (it replaced the reference to the original list with a reference to the empty greater list. You should be appending the item you just compared to the greater list instead.
I recommend filter. Easy and Graceful way.
def returnGreater(x, y):
return list(filter(lambda a:a>y, x))
It means, filter each element a in list x using lambda whether a is greater than y or not.
List Comprehensions
def returnGreater(_list, value):
return [x for x in _list if x > value]

Is there a shorter way to do exactly this?

I'm trying to find away to do this in a shorter way I don't like not using else in the end because it looks weird without it. This works for me for some reason. If I add the, " else: return True" it will only look at the first true from the list and then return True but won't check the rest... and will end the function
b = [[True, True, True], [True, True, True], [True, True, False]]
for i in range(3):
for j in range(3):
if b[i][j] == False:
return False
return True
I guess a pretty short way to accomplish this would be:
return all(i for l in b for i in l)
You can use either all or any to do this:
all(all(x) for x in b)
OR
not any(not y for x in b for y in x)
In either case, the value of the expression will be the same as the return value of your original function. Like your original loop, both of these expressions are short-circuiting: they will stop as soon as a False element in encountered in the nested lists.
In your original code, returning True on the first element naturally ends the function. That's just how return works. If you absolutely must have an else clause to please your inner aesthete (I would recommend against it), use else: continue instead. This is totally superfluous (and therefore generally undesirable), but it will instruct the loop to continue until a False is found instead of returning from the function immediately.

Resources