NachoMiguel
NachoMiguel

Reputation: 993

Dict comprehension tip

I am starting to use list comprehensions and i am a bit lost in the syntax, how can i translate this to dict comprehensions:

dict_users = Counter()
largo = len(wut)
for user in wut:
    count = 0
    for line in lines:
        if user in line:
            count += 1
    dict_users[user] = count

i have tried different variations but i keep getting it wrong.

dict_users ={user: count for user in wut count = 0 for line in lines if user in lines}

Upvotes: 0

Views: 70

Answers (3)

postelrich
postelrich

Reputation: 3496

Actually I recently read a blog post that explained nested comprehensions rather well, though I don't remember the link. To expand on jonrsharpe's answers:

for x in list_of_tuples:
    for y in x:
        do(y)

Becomes:

[do(y) for x in list_of_tuples for y in x]

So essentially you're hitting backspace until all your for's are on one line, delete colons, and then just moving final function to the front.

Keep in mind that you can't have any assignments, only for and the final action.

CAN'T MAKE A COMPREHENSION:

for x in range(10):
    x = range(x)
    for y in x:
        do(y)

CAN COMPREHEND:

for x in range(10):
    for y in range(x):
        do(y)

Upvotes: 1

chepner
chepner

Reputation: 530920

Counter already counts the items for you; you just need an appropriate sequence of lines to pass as the argument.

dictUsers = Counter(line for user in wut for line in lines if user in line)

The for clauses in the generator expression appear in the same order as the equivalent nested for loop.

Upvotes: 2

jonrsharpe
jonrsharpe

Reputation: 121975

You can't assign (count = 0 or count += 1) in a generator expression/list or dict comprehension, you need to use sum for this kind of thing instead. I think what you wanted is:

dict_users = {user: sum(user in line for line in lines) for user in wut }

Note that this uses the fact that True ('f' in 'foo') and False ('f' in 'bar') evaluate to 1 and 0 respectively when summed, as the booleans are integer subclasses. A simple example:

>>> lines = ['foo', 'bar', 'baz']
>>> users = ['ba', 'f']
>>> {user: sum(user in line for line in lines) for user in users}
{'ba': 2, 'f': 1}

But this is arguably less readable than the nested for loops you have now.

Upvotes: 4

Related Questions