Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

incrementing defaultdict inside list comprehension (Python)

I have this:

   self.lines = [...]
   cnt = defaultdict(int)
   for line in self.lines:
       cnt[line] += 1

Now this works. But I wonder if it (incrementing count of particular lines in defaultdict) could be done using list comprehension?

This is a syntax error:

   [cnt[line] += 1 for line in self.lines]

Incidentally, why can't one use expressions like this within list comprehension? It's straightforward and would greatly improved both terseness and performance of such code.

like image 760
LetMeSOThat4U Avatar asked May 15 '13 14:05

LetMeSOThat4U


2 Answers

Your list comprehension doesn't work because assignments are not expressions.

You shouldn't use list comprehension to replace a loop. Write a loop. List comprehensions are used for constructing lists.

Why do you think list comprehension would improve performance? If anything, it potentially hurts performance, because it needs to allocate and assign to the temporary list it builds, which is then never used. Imagine you have 1,000,000,000 lines in your original list.

like image 62
shx2 Avatar answered Nov 14 '22 23:11

shx2


You could use collections.Counter here:

>>> from collections import Counter
>>> lis = [1,2,3,3,3,5,6,1,2,2]
>>> Counter(lis)
Counter({2: 3, 3: 3, 1: 2, 5: 1, 6: 1})

cnt[line] += 1 is an assignment LC don't support assignments, and even using LCs for side effect is also a bad practice.

lis = []
[lis.append(x) for x in xrange(5)]  #bad

Read: Is it Pythonic to use list comprehensions for just side effects?

like image 42
Ashwini Chaudhary Avatar answered Nov 14 '22 23:11

Ashwini Chaudhary