Pulling all n-sized combinations from a list

mensanator at aol.com mensanator at aol.com
Thu Feb 16 23:06:41 EST 2006


jess.austin at gmail.com wrote:
> hi,
>
> I'm not sure why this hasn't come up yet, but this seems to beg for
> list comprehensions, if not generator expressions.  All of the
> following run in under 2 seconds on my old laptop:
>
> >>> alph = 'abcdefghijklmnopqrstuvwxyz'
> >>> len([''.join((a,b,c,d)) for a in alph for b in alph for c in alph for d in alph])
> 456976
> >>> len([''.join((a,b,c,d)) for a in alph for b in alph for c in alph for d in alph
> ...      if (a>=b and b>=c and c>=d)])
> 23751
> >>> len([''.join((a,b,c,d)) for a in alph for b in alph for c in alph for d in alph
> ...      if (a!=b and b!=c and c!=d and d!=a and b!=d and a!=c)])
> 358800
> >>> len([''.join((a,b,c,d)) for a in alph for b in alph for c in alph for d in alph
> ...      if (a>b and b>c and c>d)])
> 14950

Well, _I_ was using them in my original program to create the
conditionals, but not for the loops. So if we combine your idea
to use list comprehensions for the loop with my list comprehensions
of the conditionals, we aren't limited to asking for only 4-letter
words.

And it runs faster than my original.

Thanks.

def ooloop6(a, n, perm=True, repl=True):
    if (not repl) and (n>len(a)): return
    r0 = range(n)
    r1 = r0[1:]
    if perm and repl:                          # ok
        v = ','.join(['c%s' % i for i in r0])
        f = ' '.join(['for c%s in a' % i for i in r0])
        e = ''.join(["p = [''.join((",v,")) ",f,"]"])
        exec e
        return p
    if (not perm) and repl:                    # ok
        v = ','.join(['c%s' % i for i in r0])
        f = ' '.join(['for c%s in a' % i for i in r0])
        i = ' and '.join(['(c%s>=c%s)' % (j,j-1) for j in r1])
        e = ''.join(["p = [''.join((",v,")) ",f," if ",i,"]"])
        exec e
        return p
    if perm and (not repl):                    # ok
        v = ','.join(['c%s' % i for i in r0])
        f = ' '.join(['for c%s in a' % i for i in r0])
        i = ' and '.join([' and '.join(['(c%s!=c%s)' % (j,k) for k in
range(j)]) for j in r1])
        e = ''.join(["p = [''.join((",v,")) ",f," if ",i,"]"])
        exec e
        return p
    if (not perm) and (not repl):              # ok
        v = ','.join(['c%s' % i for i in r0])
        f = ' '.join(['for c%s in a' % i for i in r0])
        i = ' and '.join(['(c%s>c%s)' % (j,j-1) for j in r1])
        e = ''.join(["p = [''.join((",v,")) ",f," if ",i,"]"])
        exec e
        return p

p = ooloop6('abcdefghijklmnopqrstuvwxyz',4,True,True)
print
print len(p)
p = ooloop6('abcdefghijklmnopqrstuvwxyz',4,False,True)
print
print len(p)
p = ooloop6('abcdefghijklmnopqrstuvwxyz',4,True,False)
print
print len(p)
p = ooloop6('abcdefghijklmnopqrstuvwxyz',4,False,False)
print
print len(p)

"""
456976

23751

358800

14950
"""


> 
> cheers,
> Jess




More information about the Python-list mailing list