0

Going through some code from a competition that finished about a week ago, NCSS Challenge, and I am trying to replace lists and dictionaries with a comprehension but I can't manage to get the dict comprehension to work.

I had the code

for i in a:
  b[i] = b[i] + 1

and I tried replacing the code with

b = dict((i, b[i] + 1) for i in a)

but that doesn't work, I don't know how to get the dictionary to count properly

entire code:

a = [i[:-1] for i in open("votes.txt")]
b = {}

for i in open("votes.txt"):
  b[i[:-1]] = 0

#b = dict((i, b[i] + 1) for i in a)
for i in a:
  b[i] = b[i] + 1

for i in b:
  print(str(i) + ': ' + str(b[i]))

I know my code isn't very good, I just started recently, please don't judge to hard.

votes.txt:

Pedro Sanchez
Trisha Jenner
Trisha Jenner
Summer Wheatley
Pedro Sanchez
Pedro Sanchez
Trisha Jenner
Pedro Sanchez
Summer Wheatley

My code works fine using the for i in a loop but using a dictionary comprehension it displays the text below.

I expect the output to display

Pedro Sanchez: 4
Trisha Jenner: 3
Summer Wheatley: 2

when using the dict comprehension but it instead displays

Pedro Sanchez: 1
Trisha Jenner: 1
Summer Wheatley: 1
  • Well, I got the correct result with your code. – Lamanus Sep 12 '19 at 01:41
  • Related: [Using a dictionary to count the items in a list](https://stackoverflow.com/q/3496518/4518341) – wjandrea Sep 12 '19 at 01:52
  • BTW that's a generator expression in a function call, not a dict comprehension. The equivalent dict comprehension would be `{i: b[i] + 1 for i in a}`. – wjandrea Sep 12 '19 at 01:54

1 Answers1

0

Your code doesn't work because the expression on the righthand side of the equals sign gets evaluated before the lefthand name is assigned to, so each time it looks up b[i] it's seeing 0, as defined in the previous step.

As for how to fix it, ultimately you want to use collections.Counter instead, which is basically a wrapper on a dict:

from collections import Counter

with open("votes.txt") as f:
    a = f.read().splitlines()

b = Counter(a)
for k, count in b.items():
    print('{}: {}'.format(k, count))

Output:

Pedro Sanchez: 4
Trisha Jenner: 3
Summer Wheatley: 2
wjandrea
  • 28,235
  • 9
  • 60
  • 81