Question

I'm trying to make a generic function that would reduce a list like so :

func(['a','b','c'],str.join) # --> ['a','b','c','ab','ac','bc','abc']

func(['a','b','c'],lambda: a,b:a+'x'+b) # --> ['a','b','c','axb','axc','bxc','axbxc']

I don't really know how to do it. I did a few tries, but none was successful. I'm pretty sure there is a way to do it with reduce but i'm not very comfortable with the use of this function. Here are some attempts :

reduce(lambda a,b:[a,b,str(a)+str(b)],['a','b','c'])

reduce(str.join,['a','b','c'])

I think i'm missing a recursion somewhere.

I'm not asking for code especially, any help or advice is welcomed. Thanks.

Was it helpful?

Solution

itertools.combinations will give you all combinations of a certain length. We take all the combinations for each possible sublist length. We then map the function you were interested in (the lambda function, or in this case "x".join) to each of the generated combinations.

>>> import itertools as it
>>> a = ['a','b','c']
>>> l = [map("x".join, list(it.combinations(a, l))) for l in range(1,len(a)+1)]
>>> l
[['a', 'b', 'c'], ['axb', 'axc', 'bxc'], ['axbxc']]

Now l is a list of lists that we want to flatten:

>>> [ x for y in l for x in y]
['a', 'b', 'c', 'axb', 'axc', 'bxc', 'axbxc']

OTHER TIPS

How's this?

>>> import itertools
>>> def func(mylist, letter):
...     L = []
...     for i in range(len(mylist)):
...             L.append(list(itertools.combinations(mylist,i+1)))
...     return [letter.join(i) for i in itertools.chain.from_iterable(L)]
... 
>>> func(['a','b','c'], 'x')
['a', 'b', 'c', 'axb', 'axc', 'bxc', 'axbxc']
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top