6

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.

LetMeSOThat4U
  • 6,470
  • 10
  • 53
  • 93
  • 1
    Why do you think it would improve the performance? You still need to iterate over self.lines, and now you've introduced the overhead of creating a list where you had none before. And it's no more terse: you traded a colon and a newline for a pair of square brackets. – chepner May 15 '13 at 14:32
  • @chepner, I added a similar note to my answer at the same time you wrote yours ;) – shx2 May 15 '13 at 14:35

2 Answers2

5

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.

shx2
  • 61,779
  • 13
  • 130
  • 153
4

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?

Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504