Pulling all n-sized combinations from a list
Michael Spencer
mahs at telcopartners.com
Wed Feb 8 19:52:15 EST 2006
Swroteb wrote:
> Paul Rubin wrote:
>> I think the natural approach is to make a generator that yields a
>> 5-tuple for each combination, and then have your application iterate
>> over that generator. Here's my version:
>>
>> def comb(x,n):
>> """Generate combinations of n items from list x"""
>> if n==0:
>> yield []
>> return
>> for i in xrange(len(x)-n+1):
>> for r in comb(x[i+1:], n-1):
>> yield [x[i]] + r
>>
>> for c in comb([1,2,3,4,5], 3):
>> print c
>>
>> The output is:
>> >>>
>> [1, 2, 3]
>> [1, 2, 4]
>> [1, 2, 5]
>> [1, 3, 4]
>> [1, 3, 5]
>> [1, 4, 5]
>> [2, 3, 4]
>> [2, 3, 5]
>> [2, 4, 5]
>> [3, 4, 5]
>> >>>
>
> Ah, this definitely seems to work! It's a lot nicer in appearance than
> my previous code, that's for sure. It actually runs in approximately
> the same amount of time though. So, using your comb method, I have the
> following code now:
>
> myCombinations = comb(myList, 5)
> for a, b, c, d, e in myCombinations:
> # my code
>
> myList is 48 elements in size, so I'm going to get 1712304
> combinations. From what I can tell, my speed problems aren't in the
> list generation anymore.
>
> Thanks for the assistance, Paul! I appreciate it. :)
>
If you're concerned about speed, and don't mind lack of flexibility, spelling
out the iteration within your function is much faster:
def comb(seq):
indices = range(len(seq))
for ia in indices:
a = seq[ia]
for ib in indices[ia+1:]:
b = seq[ib]
for ic in indices[ib+1:]:
c = seq[ic]
for id in indices[ic+1:]:
d = seq[id]
for ie in indices[id+1:]:
e = seq[ie]
This is roughly 30 times faster on my box than the general solution above
Michael
More information about the Python-list
mailing list