Skip to content Skip to sidebar Skip to footer

Making A Function Only Run For Certain Conditions In Python

G'day! So I have a function which is taking the elements from two lists, the first of which is in a standard list format, the second being a list of lists, the inner lists containi

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() fromitertoolswith 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"