5 queens

George Sakkis george.sakkis at gmail.com
Mon Dec 24 15:26:48 EST 2007


On Dec 23, 7:04 am, Steven D'Aprano wrote:

> def combinations(seq, n):
>     if n == 0:
>         yield []
>     else:
>         for i in xrange(len(seq)):
>             for cc in combinations(seq[i+1:], n-1):
>                 yield [seq[i]]+cc
>
> >>> for c in combinations(range(4), 3):
>
> ...     print c
> ...
> [0, 1, 2]
> [0, 1, 3]
> [0, 2, 3]
> [1, 2, 3]

Or if you only need to iterate over each combination once instead of
keeping around more than one of them, below is a more efficient
version that reuses the same list for all combinations. Also it
doesn't require the input sequence to implement slicing so it can be
used e.g. with xrange:

def itercombos(seq, n):
    def ifill(combo, i, start, end=len(seq), seq=seq, n=n):
        if i == n:
            yield combo
        else:
            i1 = i+1
            for j in xrange(start,end):
                combo[i] = seq[j]
                for combo in ifill(combo, i1, j+1):
                    yield combo
    for combo in ifill(n*[None],0,0):
        yield combo

>>> for c in itercombos(xrange(4), 3): print c

[0, 1, 2]
[0, 1, 3]
[0, 2, 3]
[1, 2, 3]

>>> for c in combinations(xrange(4), 3): print c

Traceback (most recent call last):
  File "combs.py", line 54, in <module>
    for c in combinations(xrange(4), 3): print c
  File "combs.py", line 12, in combinations
    for cc in combinations(seq[i+1:], n-1):
TypeError: sequence index must be integer, not 'slice'


George



More information about the Python-list mailing list