Making A Function Only Run For Certain Conditions In Python
Solution 1:
Could you pad the first list with None where its not long enough and trim it where its too long.
then only carry out the function where x is not None otherwise return y
i've tried to code an example
from itertools import chain
first = [0, 1, 2, 3, 1, 5, 6, 7, 1, 2, 3, 5, 1, 1, 2, 3, 5, 6]
second = [
[(13, 12, 32), (11, 444, 25)],
[(312, 443, 12), (123, 4, 123)],
[(545, 541, 1), (561, 112, 560)],
[(13, 12, 32), (11, 444, 25)],
[(312, 443, 12), (123, 4, 123)],
[(545, 541, 1), (561, 112, 560)],
]
defadd(x, y):
return x + y
defpad(list,length):
for i inrange(length-len(list)):
list.append(None)
returnlist[0:length]
first = pad(first,len(list(chain(*(chain(*second))) )))
# There is probably a better way to achieve this
foo = [add(x, y) if x else y for x, y inzip(first, chain(*(chain(*second))))]
bar = [foo[i:i+3] for i inrange(0, len(foo), 3)]
second = [bar[i:i+2] for i inrange(0, len(foo) / 3, 2)]
print second
Solution 2:
since zip
only zips to the smaller of the two lists, it isn't too useful here. You could create your own algorithm that applies a function to two lists in the way you specify:
from itertools import *
defflatten(seq):
returnlist(chain(*(chain(*seq))))
defspecial_apply(a,b, func):
"""
applies a two argument function to the given flat lists.
The result will have the same size as the second list, even if the first list is shorter.
"""
result = []
for i inrange(len(b)):
if i < len(a):
element = func(a[i], b[i])
#if a ran out of elements, just supply an unmodified element of belse:
element = b[i]
result.append(element)
return result
defadd(x,y):
return x+y
a = [1,1,1]
b = [[(13,12,32),(11,444,25)],[(312,443,12),(123,4,123)],[(545,541,1),(561,112,560)]]
foo = special_apply(a, flatten(b), add)
bar = [foo[i:i+3] for i inrange(0, len(foo), 3)]
result = [bar[i:i+2] for i inrange(0, len(foo) / 3, 2)]
print result
Result:
[[[14, 13, 33], [11, 444, 25]], [[312, 443, 12], [123, 4, 123]], [[545, 541, 1], [561, 112, 560]]]
Solution 3:
I think this does everything you want, if I've understood all the requirements. The major difference from your code is that it also usesizip_longest()
fromitertools
with a customfillvalue
, instead of plainzip()
. It also just checks for the special cases involving empty input lists at the beginning, which seemed easier than trying to devise list comprehensions or whatever to handle them.
from itertools import chain, izip_longest
def add(x, y):
return x + y
def func(first, second):
if notfirst: returnsecond
if notsecond: return []
second= chain(*(chain(*second))) # flatten
foo = [add(x, y) for x, y in izip_longest(first, second, fillvalue=0)]
bar = [tuple(foo[i:i+3]) for i inrange(0, len(foo), 3)]
return [bar[i:i+2] for i inrange(0, len(foo) /3, 2)]
if __name__ =='__main__':
first= [
0, 1, 2, 3, 1, 5,
6, 7, 1, 2, 3, 5,
1, 1, 2, 3, 5, 6]
second= [
[(13, 12, 32), (11, 444, 25)], [(312, 443, 12), (123, 4, 123)],
[(545, 541, 1), (561, 112, 560)], [(13, 12, 32), (11, 444, 25)],
[(312, 443, 12), (123, 4, 123)], [(545, 541, 1), (561, 112, 560)],
]
print func(first, second)
print
print func(first[:-1], second) # 1st shorter, as many as poss, rest unchanged
print
print func(first, second[:-1]) # 2nd shorter, do onlyas many asinsecond
Post a Comment for "Making A Function Only Run For Certain Conditions In Python"