galaxyan
galaxyan

Reputation: 6111

how to re-write for loop to list comprehension

I wonder if there is a way to re write following code to list comprehension. Thank you

inputDict is a dict

result = {}
for key in inputDict:
    total = 0
    for nodes in inputDict :
        total = total + (key in inputDict[nodes])
    result.update({key : total})

Upvotes: 1

Views: 102

Answers (2)

user2357112
user2357112

Reputation: 280335

Not a list comprehension, since you're not building a list. However, the operation you're trying to perform, which appears to be counting how many nodes link to each node, can easily be done by using collections.Counter to count how many times each node appears in the values of inputDict:

import collections
import itertools
result = collections.Counter(itertools.chain.from_iterable(inputDict.values()))

itertools.chain takes inputDict.values() and strings all the lists of nodes in there into one big iterator. (Or maybe those are sets of nodes. It's hard to tell.) collections.Counter then counts how many times it sees each element. The result is a collections.Counter instance, which behaves mostly like a dict. There are a few differences, though, so if you need a result that's exactly of dict type, you can call dict on it:

result = dict(result)

Note that Counter returns a count of 0 for items not in the Counter, but dict doesn't do that. If you call dict on it, you may need to fill in a count of 0 for nodes that never appeared in inputDict.values().


The use of Counter and chain can hide some of what's going on here, so here's how you'd write that without importing library code:

result = {}

# Initialize counts to 0, to make sure nodes that don't appear in the values have the
# right count and to make sure we don't need to check `if node in result` later.
for node in inputDict:
    result[node] = 0

# Go through and count node occurrences.
for adjacent_nodes in inputDict.values():
    for node in adjacent_nodes:
        result[node] += 1

There isn't an easy way to turn this into a comprehension without algorithmic complexity sacrifices, which is part of why collections.Counter exists.

Upvotes: 1

Artsiom Rudzenka
Artsiom Rudzenka

Reputation: 29093

If i understood you correctly than you can try:

result = dict((key, sum(key in inputDict[nodes] for nodes in digraph)) for key in inputDict)

Or if you need a list:

result = [(key, sum(key in inputDict[nodes] for nodes in digraph)) for key in inputDict]

Or:

result = [(key, sum(key in vals for nodes in digraph)) for key, vals in inputDict]

Upvotes: 1

Related Questions