Hi, my name is Jesse and I abuse list comprehensions.

March 28th, 2008 § 11 comments

I just found myself being quite abusive.

I have a series of dict{key:[list]) style objects, and I wanted to unpack it, con­vert it to a string, etc. (yes, vari­able names have been changed to pro­tect the innocent)

?View Code PYTHON
1
return ',',join(['{{whizbang|%s}}' % i['foo'] for i in [ i for i in myDict[keyname]]])

Now, this could only be bet­ter if I:

  • Included a lambda
  • Had another nested comprehension

Other than the fact that what I wrote above is next to untestable — it’s also hard to under­stand unless well, you’re me. In order to debug it, you’d have to pprint the inbound dict and slowly unravel (from left to right) the oper­a­tions being done.

Luck­ily, there’s no math there!

So, I “cleaned” it up:

?View Code PYTHON
1
2
3
4
whizlist = []
for item in [k for k in myDict[keyname]]:
    whizlist.append('{{whizbang|%s}}' % item['foo'])
return ','.join(whizlist)

Hmm, I still seem to be jug­gling chain­saws here. Let’s go for the “easy” button:

?View Code PYTHON
1
2
3
4
whizlist = []
for item in myDict[keyname]:
	whizlist.append('{{whizbang |%s}}' % item['foo'])
return ','.join(whizlist)

I could argue that the first is “faster” (although I’d need to prove it) — but ulti­mately the final “un-optimized” ver­sion is more pythonic.

  • Nes

    I might be miss­ing some­thing by why didn’t you just do:

    return ‘,’,join( ‘{{whizbang|%s}}’ % i[’foo’] for i in myDict[keyname] )

    ?

  • jnoller

    Hmm, good ques­tion. I’ll have to try that one out, although I still have to go with option 3

  • mike

    not to men­tion return ‘,’.join([‘{{whizbang|%s}}’ % v for v in myDict[keyname].values()])

  • http://www.hardcoded.net Vir­gil Dupras

    What about:

    whizzes = (d[’foo’] for d in myDict[keyname])
    return ‘,’.join(‘{{whizbang |%s}}’ % whiz for whiz in whizzes)

  • Mar­tin

    The fol­low­ing expres­sions are equiv­a­lent, which one would you choose? ;-)

    mylist
    [x for x in mylist]
    [y for y in [x for x in mylist]]
    [z for z in [y for y in [x for x in mylist]]]
    [q for q in [z for z in [y for y in [x for x in mylist]]]]

    ok… you get the point. (Strictly speak­ing they are not com­plely equiv­a­lent since the first of them doesn’t yield a copy of the list but is rather a ref­er­ence to the original)

  • jnoller

    Still not con­vo­luted enough

  • jnoller

    [q for q in [z for z in [y for y in [x for x in mylist]]]]

    mmmm. Deli­cious. Jam a lambda and a cou­ple of .method() calls on the objects being iter­ated through and it will be complete.

  • http://www.bouncybouncy.net Justin

    or

    return ‘,’,join( ‘{{whizbang|%(foo)s}}’ % i for i in myDict[keyname] )

  • http://www.doughellmann.com/ Doug Hell­mann

    I find list com­pre­hen­sions eas­ier to grok when they are writ­ten on mul­ti­ple lines.

    [ value
    for item in sequence
    (if con­di­tion)
    ]

  • http://gpiancastelli.wordpress.com/ Giulio Piancastelli

    I could argue that the first has a typo, although you’d need to exe­cute it.

  • http://gpiancastelli.wordpress.com/ Giulio Piancastelli

    I could argue that the first has a typo, although you’d need to exe­cute it.

What's this?

You are currently reading Hi, my name is Jesse and I abuse list comprehensions. at jessenoller.com.

meta