0
votes

I don't understand why this list comprehension isn't correct. If I understand list comprehensions correctly, it should first iterate over the dictionaries in the list [dict1, dict2] and then over key-value pairs in each dictionary and return the values. Were am I wrong?

dict1 = {'a' : 1, 'b' : 2, 'c' : 3}
dict2 = {'c' : 2, 'd' : 3, 'e' : 4}
[value for key, value in d.items()
       for d in [dict1, dict2]]

It gives the following error:

NameError                                 Traceback (most recent call last)
<ipython-input-78-e8d31c1fb24a> in <module>()
      1 dict1 = {'a' : 1, 'b' : 2, 'c' : 3}
      2 dict2 = {'c' : 2, 'd' : 3, 'e' : 4}
----> 3 [value for (key, value) in d.items() 
      4        for d in [dict1, dict2]]

NameError: name 'd' is not defined

I would expect:

[1,2,3,2,3,4]
3
note you can iterate over d.values() instead of d.items() which just clutters your code, if you are only interested in values...juanpa.arrivillaga
Also, if you are iterating over a sequence literal inside a list comprehension, may I advise to use tuples... it makes it more clear IMHO: [val for d in (dict1,dict2) for val in d.values()]juanpa.arrivillaga

3 Answers

1
votes

Perhaps a more readable way might be this

from itertools import chain

d = [{'a' : 1, 'b' : 2, 'c' : 3}, {'c' : 2, 'd' : 3, 'e' : 4}]
chain.from_iterable(map(dict.values, d))

[3, 1, 2, 2, 4, 3]

Map each dict to its values only and chain the result. The order is not the same, but you'd expect that.

0
votes

The order of the nested for loop in your list-comprehension is reversed. In list-comprehension, the first for loop is the outer for loop which executes firstly, then the second for loop. So if you switch the order, it should just work fine:

[value for d in [dict1, dict2] for key, value in d.items()]

# [1, 3, 2, 2, 4, 3]
0
votes

Try to use the advantage of lambda function in Python:

map(lambda x: x[1], reduce(lambda x,y: x.items()+y.items(),  [dict1, dict2]))

This will give what you want.