list comprehension
Patrick Maupin
pmaupin at gmail.com
Tue Jan 24 11:16:41 EST 2006
Duncan Booth wrote:
> I prefer writing an 'if' statement here, Bryan prefers 'get', that's just a
> choice of style. But 'setdefault' here, that has no style.
Well, I'm often told I have no style, and I _did_ admit that it's an
abuse of setdefault. However, I often use setdefault to populate
nested dictionaries, or dictionaries of sets or lists, e.g.:
for x, y in somebiglist:
bigdict.setdefault(x,set()).add(y) # Strips duplicates
for x, y in somebiglist:
bigdict.setdefault(x,[]).append(y) # Preserves duplicates
To my mind, this latter is so much cleaner and clearer than any of the
alternatives that it just isn't funny:
for x, y in somebiglist:
if x in bigdict:
bigdict[x].append(y)
else:
bigdict[x] = [y]
for x, y in somebiglist:
if x not in bigdict:
bigdict[x] = []
bigdict[x].append(y)
for x, y in somebiglist:
try:
bigdict[x].append(y)
except KeyError:
bigdict[x] = [y]
etc.
Since I use setdefault in this manner quite often, I am very
comfortable with it. On a single line I know what I am creating (list,
dict, set, etc.), what the default value is, and how it is being
modified.
Because I am NOT a believer in the Perl idiom of TMTOWTDI, and because,
TO ME, setdefault screams "This line is creating and subsequently
modifying a dictionary entry", setdefault is absolutely my first choice
for this particular task.
Having said that, my enthusiasm for setdefault (for the given problem!)
IS tempered somewhat by having to abuse a list as a mutable integer.
That is the only reason that I concede that my solution is an abuse of
setdefault, but the setdefault idiom is (to me) so clear and compelling
that I view it as a toss-up whether to use a single line setdefault or
an if/else in this case.
And, as I mentioned earlier, if I had to do this same thing LOTS of
times in a program, I most likely would code a class (perhaps not as
fancy as a true mutable int, but certainly something with an increment
method), because, IMO, it would be a lot cleaner (hmmm, maybe there's
no style points in that) than tons and tons of if/else statements.
Regards,
Pat
More information about the Python-list
mailing list