Python in operator is not working - python

When I run this code, nothing shows up. For example I call ind(1, [1, 2, 3]), but I don't get the integer 13.
def ind(e, L):
if (e in L == True):
print('13')
else:
print('12')

Operator precedence. If you put ( and ) around e in L it will work:
def ind(e, L):
if ((e in L) == True):
print('13')
else:
print('12')
ind(1, [1, 2, 3])
But testing for True can be done (and is the usual idiom) done without the True
def ind(e, L):
if (e in L):
print('13')
else:
print('12')
ind(1, [1, 2, 3])
Edit: as a bonus you can even use True and False to keep/nullify things. With your example:
def ind(e, L):
print('13' * (e in L) or '12')
ind(1, [1, 2, 3])
ind(4, [1, 2, 3])
And this ouputs:
13
12
Because e in L has first been evaluated to True and 13 * True is 13. The 2nd part of the boolean expression is not looked up.
But when calling the function with 4, then the following happens:
`13` * (e in L) or '12` -> `13` * False or '12' -> '' or '12' -> 12
Becase and empty string evaluates to False too and therefore the 2nd part of the or boolean expression is returned.

It should be
def ind(e, L):
if (e in L):
print ('13')
else:
print ('12')
Here ind(1,[1,2,3]) will print 13
And here's my proof that the above syntax runs in my machine:

Related

Function that find combination of values that sums to a given number

This post Finding Combinations to the provided Sum value presents the function subsets_with_sum(). It finds a combination of values in an array which the sum is equal to a given value. But since the post is over 6 years old, I made this post to ask: how does this function work? What is it doing?
def subsets_with_sum(lst, target, with_replacement=False):
x = 0 if with_replacement else 1
def _a(idx, l, r, t):
if t == sum(l): r.append(l)
elif t < sum(l): return
for u in range(idx, len(lst)):
_a(u + x, l + [lst[u]], r, t)
return r
return _a(0, [], [], target)
To start, I'll just add some line breaks to make it a bit easier to read:
def subsets_with_sum(lst, target, with_replacement=False):
x = 0 if with_replacement else 1
def _a(idx, l, r, t):
if t == sum(l):
r.append(l)
elif t < sum(l):
return
for u in range(idx, len(lst)):
_a(u + x, l + [lst[u]], r, t)
return r
return _a(0, [], [], target)
First thing you'll notice is that the subsets_with_sum defines a function and calls it once in the last return statement. The first element is your list from which you sample values, the second is the target sum, and third is an parameter that tells the function whether a single element from lst can be used multiple times.
Because the _a is defined within the subsets_with_sum it is enclosed with the values passed to subsets_with_sum - this is important, lst is the same for every recursive call of _a. The second thing to notice is that l is a list of values, whereas r is a list of lists. Importantly, l is a different object for each _a call (that's due to l + [lst[u]] resulting in a copy of l concatenated with [lst[u]]). However, r denotes the same object for each _a call - r.append(l) modifies it in place.
I'll start with with_replacement == True because I find it simpler. With the first call _a is passed 0, [], [], target. It then checks if t == sum(l) and appends it to r, hence the only elements of r will be lists that sum to t (or target). If sum(l) that recursive branch is discarded by returning None. If the elements of l sum to a value lesser then target then for each element from the lst the element is appended to a copy of l and _a is called with that list. Here's an amended version of the function that prints out the steps, so we can inspect what happens:
def subsets_with_sum(lst, target, with_replacement=False):
x = 0 if with_replacement else 1
def _a(idx, l, r, t, c):
if t == sum(l):
r.append(l)
elif t < sum(l):
return
for u in range(idx, len(lst)):
print("{}. l = {} and l + [lst[u]] = {}".format(c, l, l + [lst[u]]))
_a(u + x, l + [lst[u]], r, t, c+1)
return r
return _a(0, [], [], target, 0)
Calling subsets_with_sum([1,2,3], 2, True) the following gets printed (I re-ordered and separated the printed lines a bit so they're easier to read):
0. l = [] and l + [lst[u]] = [1]
0. l = [] and l + [lst[u]] = [2]
0. l = [] and l + [lst[u]] = [3]
1. l = [1] and l + [lst[u]] = [1, 1]
1. l = [2] and l + [lst[u]] = [2, 2]
1. l = [2] and l + [lst[u]] = [2, 3]
1. l = [1] and l + [lst[u]] = [1, 2]
1. l = [1] and l + [lst[u]] = [1, 3]
2. l = [1, 1] and l + [lst[u]] = [1, 1, 1]
2. l = [1, 1] and l + [lst[u]] = [1, 1, 2]
2. l = [1, 1] and l + [lst[u]] = [1, 1, 3]
You can see that the right column (l + [lst[u]]) at a level c is equal to the left column (l) at a level c + 1. Furthermore, observe that [3] - the last line where c == 0 doesn't make it past the elif t < sum(l), hence it doesn't get printed. Similarly, [2] at c == 1 gets appended to r, but nonetheless the branch continues to the next level, since one or more elements of the lst might be equal to 0, hence appending them to [2] might result in another list that sums to the target.
Also, observe that for each list at certain level c, whose last element is lst[u] will appear len(lst) - u-times at the next level, c + 1, because that's the number of combinations of the list for each lst[z], where z >= u.
So what happens with with_replacement == False (the default case)? Well, in that case each time lst[u] is added to l and sum(l) < t, so that that specific instance of l continues to the next recursion level only lst[z] can be added to the list, where z > u, since u + 1 is passed to the respective _a call. Let's look what happens when we call subsets_with_sum([1,2,3], 2, False):
0. l = [] and l + [lst[u]] = [1]
0. l = [] and l + [lst[u]] = [3]
0. l = [] and l + [lst[u]] = [2]
1. l = [1] and l + [lst[u]] = [1, 1]
1. l = [1] and l + [lst[u]] = [1, 2]
1. l = [1] and l + [lst[u]] = [1, 3]
1. l = [2] and l + [lst[u]] = [2, 2]
1. l = [2] and l + [lst[u]] = [2, 3]
2. l = [1, 1] and l + [lst[u]] = [1, 1, 1]
2. l = [1, 1] and l + [lst[u]] = [1, 1, 2]
2. l = [1, 1] and l + [lst[u]] = [1, 1, 3]
Now observe that for each list at certain level c, whose last element is lst[u] will appear len(lst) - u - 1-times at the next level, c + 1, because that's the number of combinations of the list for each lst[z], where z > u. Compare this with the with_replacement=True analyzed above.
I suggest you play around with it somewhat more until you understand it better. Regardless of substitution, what is important to realize is that the return statements always return to the caller. The first call of the _a returns to the subsets_with_sum which then returns to the caller (presumably you or some other function). All other (recursive) calls to _a return to the previous instances of _a calls which just discard the returned value (or more precisely, don't bother to do anything with it). The reason you get back the right r is because it behaves somewhat like a global value - each _a call that finds a solution, adds it to the same r.
Finally, the subsets_with_sum doesn't work exactly like I'd expect it to based on its desired functionality. Try the following two calls: subsets_with_sum([2,2,1], 5, True) and subsets_with_sum([2,2,1,1,1], 5, False).

Check if all values in a list are bigger than certain number x and smaller than y?

def fun_lst(lst, a, b):
if min(lst)<b and max(lst)>a:
return True
return False
How do I check if the values in the list are bigger than a and smaller than b? I tried the above, but in this example: fun_lst([-1, 3.5, 6], -2.4, 0)the function returns True and it supposed to return False.
Do this:
def fun_lst(lst, a, b):
if min(lst) > a and max(lst) < b:
return True
return False
print(fun_lst([-1, 3.5, 6], -2.4, 0) )
Output:
False
Doing min(lst) > a ensures every element is bigger than a.
Doing max(lst) < b ensures every element is smaller than b.
Alternate solution:
def fun_lst(lst, a, b):
return all(a < elem < b for elem in lst)
You can try this one liner if you like
all([num < b and num > a for num in lst])
This code here will check each item in the list, if an item is found that is not greater than a and less than b then it returns false, otherwise it returns true.
def fun_lst(lst, a, b):
for item in lst:
if not a < item < b:
return False
return True
myList = [1,2,3,4,5,6,7,8,9]
lower_limit = 3
upper_limit = 8
bool_output = all([i > lower_limit and i < upper_limit for i in myList])
print(bool_output)
False
myList = [1,2,3,4,5,6,7,8,9]
lower_limit = 0
upper_limit = 10
bool_output = all([i > lower_limit and i < upper_limit for i in myList])
print(bool_output)
True
you should try this:
def fun_lst(lst, a, b):
return all(n > a and n < b for n in lst)
If you have a provision to use numpy try this
In [1]: import numpy as np
In [3]: np.array(b)
Out[3]: array([ 3, 1, 4, 66, 8, 3, 4, 56])
In [17]: b[(2<b) & (b<5)]
Out[17]: array([3, 4, 3, 4])
Different a method:
def fun_lst(lis, x, y):
list = [i>x and i<y for i in lis]
return False if False in list else True
It's a little easy:
def fun_lst(lis, x, y):
return x<max(lis)<y
lambda version:
fun_lst = lambda lis, x, y: x<max(lis)<y
Outputs:
fun_lst([-1, 3.5, 6], -2.4, 0) #Output: False

sumOfTwo Time Limit Exceeded CodeFights Interview Practice

I am attempting the sumOFTwo challenge on CodeFights.com but I unfortuantly cannot complete it to view the solution. All my tests suceedd until the 15th hidden test and it says it exceeds the time limit.
The challenge is - You have two integer arrays, a and b, and an integer target value v. Determine whether there is a pair of numbers, where one number is taken from a and the other from b, that can be added together to get a sum of v. Return true if such a pair exists, otherwise return false.
My code is -
def sumOfTwo(a,b,v):
a.sort()
b.sort()
if(0 in a and v in b):
return True
elif(v in a and 0 in b):
return True
else:
for i in a:
for j in b:
if(i + j == v):
return True
return False
I know it could be shrunken down to about 6 lines of code, but I kept adding in lines that could help the code possibly finish quicker. Are there any other optimizations I am missing.
You could just turn one of the lists to set, iterate over the other list and see if v - value_from_list exists in the set:
def sumOfTwo(a,b,v):
b = set(b)
return any(v - x in b for x in a)
print(sumOfTwo([3, 6, 7], [2, 1], 9))
print(sumOfTwo([3, 6, 7], [2, 1], 10))
print(sumOfTwo([3, 6, 7], [2, 1], 4))
print(sumOfTwo([3, 6, 7], [2, 1], 3))
Output:
True
False
True
False
Time complexity of above in O(n).
Here is how I solved it in Python:
def sumOfTwo(a, b, v):
#No need to iterate a huge list, if the other list is empty
if not a or not b:
return False
#kill duplicates
b = set(b)
#iterate through list a to look if the wanted difference is in b
for x in a:
if (v-x) in b:
return True
return False
This is what I have. It passes all the tests, hidden included, but it takes too long on four of the hidden tests.
def sumOfTwo(a, b, v):
for i in a:
if((v-i) in b):
return True
return False
#niemmi's answer passes the time limit portion. I didn't know sets were faster than arrays/lists. Thanks, good to know. If I add b=set(b) before the for loop, it passes.
Try this:
function sumOfTwo(a, b, v) {
if(a.length==0)return false;
if(b.length==0)return false;
for(var i=0; i<a.length; i++){
if(b.indexOf(v-a[i])>0){
return true;
}
}
return false;}

Vector input gives output vector `[0,...,0]` in Python

I'm trying to create a vector class in Python. I'm not so far yet, and stuck already.
This is my current code:
class vector:
def __init__(self, n, l = []):
self.v = []
if(isinstance(n, int)):
x = int(n)
if (x < 0):
return SyntaxError
else:
self.v += [0.0] * x
else:
self.v += n
def __str__(self):
return str(self.v)
The problem is, that when my input is
>>> u = vector(3,3.14)
>>> print(u)
then my ouput is
[0.0, 0.0, 0.0]
But I want it to be
[3.14,3.14,3.14]
and I also want the following:
>>> v=[3,[2.0,3.14,-5])
>>> print(v)
[2.0,3.14,-5]
What is the problem in my script?
Thanks!
You have [0.0] * x, but I think you mean [l] * x.
It really helps to clear up what kind of cases your code must support and write it down. It also helps to define a clear list of input and output combinations, you can use them as a test:
class Vector(object):
def __init__(self, n, l):
if isinstance(l, (list, tuple)): # l is a list, check length
if len(l) == n: # length as required, keep as is
pass
elif len(l) > n: # to long, use only the first n items
l = l[0:n]
elif len(l) < n: # to short, append zeros
l += [0] * (n - len(l))
elif isinstance(l, (int, float)): # create a list containing n items of l
l = [l] * n
self.v = l
def __str__(self):
return str(self.v)
Add some tests:
def test(a, b):
print 'input: {}, output: {}'.format(a, b)
if str(a) != b:
print('Not equal!')
test(Vector(3, 3.14), '[3.14, 3.14, 3.14]')
test(Vector(3, [4, 4, 4]), '[4, 4, 4]')
test(Vector(2, [4, 4, 4]), '[4, 4]')
test(Vector(4, [4, 4, 4]), '[4, 4, 4, 0]')
test(Vector(3, [2.0, 3.14, -5]), '[2.0, 3.14, -5]')

Repeat function python

I'm stuck at higher-order functions in python. I need to write a repeat function repeat that applies the function f n times on a given argument x.
For example, repeat(f, 3, x) is f(f(f(x))).
This is what I have:
def repeat(f,n,x):
if n==0:
return f(x)
else:
return repeat(f,n-1,x)
When I try to assert the following line:
plus = lambda x,y: repeat(lambda z:z+1,x,y)
assert plus(2,2) == 4
It gives me an AssertionError. I read about How to repeat a function n times but I need to have it done in this way and I can't figure it out...
You have two problems:
You are recursing the wrong number of times (if n == 1, the function should be called once); and
You aren't calling f on the returned value from the recursive call, so the function is only ever applied once.
Try:
def repeat(f, n, x):
if n == 1: # note 1, not 0
return f(x)
else:
return f(repeat(f, n-1, x)) # call f with returned value
or, alternatively:
def repeat(f, n, x):
if n == 0:
return x # note x, not f(x)
else:
return f(repeat(f, n-1, x)) # call f with returned value
(thanks to #Kevin for the latter, which supports n == 0).
Example:
>>> repeat(lambda z: z + 1, 2, 2)
4
>>> assert repeat(lambda z: z * 2, 4, 3) == 3 * 2 * 2 * 2 * 2
>>>
You've got a very simple error there, in the else block you are just passing x along without doing anything to it. Also you are applying x when n == 0, don't do that.
def repeat(f,n,x):
"""
>>> repeat(lambda x: x+1, 2, 0)
2
"""
return repeat(f, n-1, f(x)) if n > 0 else x

Categories

Resources