list comprehension

mensanator at aol.com mensanator at aol.com
Fri Jun 30 14:00:14 EDT 2006


Andy Dingley <dingbat at codesmiths.com> wrote:
> Simon Forman wrote:
>
> > There's more to it, but that's the basic idea.
>
> This much I knew, but _why_ and _when_ would I choose to use list
> comprehension (for good Python style), rather than using a simple
> "traditional" loop ?

To make dynamically nested for loops.

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,"]"])
    print 'Permutations with Replacement'
    print e
    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,"]"])
    print 'Combinations with Replacement'
    print e
    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,"]"])
    print 'Permutations without Replacement'
    print e
    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,"]"])
    print 'Combinations without Replacement'
    print e
    exec e
    return p

s = 'abcde'

p = ooloop6(s,2,True,True)
print
p = ooloop6(s,2,False,True)
print
p = ooloop6(s,2,True,False)
print
p = ooloop6(s,2,False,False)
print

p = ooloop6(s,4,True,True)
print
p = ooloop6(s,4,False,True)
print
p = ooloop6(s,4,True,False)
print
p = ooloop6(s,4,False,False)
print


"""
Permutations with Replacement
p = [''.join((c0,c1)) for c0 in a for c1 in a]

Combinations with Replacement
p = [''.join((c0,c1)) for c0 in a for c1 in a if (c1>=c0)]

Permutations without Replacement
p = [''.join((c0,c1)) for c0 in a for c1 in a if (c1!=c0)]

Combinations without Replacement
p = [''.join((c0,c1)) for c0 in a for c1 in a if (c1>c0)]

Permutations with Replacement
p = [''.join((c0,c1,c2,c3)) for c0 in a for c1 in a for c2 in a for c3
in a]

Combinations with Replacement
p = [''.join((c0,c1,c2,c3)) for c0 in a for c1 in a for c2 in a for c3
in a if (c1>=c0) and (c2>=c1) and (c3>=c2)]

Permutations without Replacement
p = [''.join((c0,c1,c2,c3)) for c0 in a for c1 in a for c2 in a for c3
in a if (c1!=c0) and (c2!=c0) and (c2!=c1) and (c3!=c0) and (c3!=c1)
and (c3!=c2)]

Combinations without Replacement
p = [''.join((c0,c1,c2,c3)) for c0 in a for c1 in a for c2 in a for c3
in a if (c1>c0) and (c2>c1) and (c3>c2)]

"""


>
> If I want to generate something that's simply ( [1] + [2] + [3]+... )
> then list comprehension is obviously the tool of choice. I suspect
> though that there's more to it than this. Is list comprehension also
> treatable as a sneaky concise formulation for nested lists, where
> they're as much about selection of individual elements, so much as
> concatenation of the sequence?
>
> What happens if a comprehension has side effects, such as from calling
> a function within it? Is this regarded as good or bad coding style? Is
> it evil (as structured programming would claim) or is it  a concise
> formulation for an iterator or visitor pattern ?




More information about the Python-list mailing list