Python - re-listing dictionaries and unpacking

Given a flat list of simple dictionaries

lst = [{'key1': 1}, {'key2': 2}, {'key3': 3}] 

I would like to find a dict that gives the minimum value evaluated using a method not described here. My first idea was to iterate over the list to check the dict dict, but this fails:

 for k, v in [x.items() for x in lst]: print(k, v) 

The result of a ValueError (as well as using a generator instead of a list):

 for k, v in [x.items() for x in lst]: ValueError: not enough values to unpack (expected 2, got 1) 

but

 for x in lst: for k, v in x.items(): print(k, v) 

gives

 key1 1 key2 2 key3 3 

As expected. I assume that all approaches work as intended (if only PEBKAC), but why doesn't it work using list comprehension? Can anyone enlighten me?

Edit: I am using python 3, and I know that items () gives dict_view, but I don't understand why the logic is not working.

+7
python list-comprehension argument-unpacking
source share
4 answers

You are missing an iteration level.

Typically, dicts has more than one key / value pair. dict.items() converts the entire dictionary into a sequence of tuples in the form (key, value) . In your case, each dictionary has only one element, but the result of items() is still a tuple of tuples.

If you print the result [x.items() for x in lst] , you will see that the result is a list of dict_view elements; each of them can be repeated.

+4
source share

Instead of taking the first element of your dict_view , you can add one level of indentation (as @DanielRoseman suggested) in your understanding of the list:

 for k, v in [(k, v) for x in lst for (k, v) in x.items()]: print(k, v) 

Exit

 key1 1 key2 2 key3 3 

as was expected.

+1
source share

Try to unzip lst step by step to understand how it is built.

 >>> in: lst[0].items() >>> out: [('key1', 1)] 

Your result (equal to your x.items() expression in the list comprehension) is another list containing your tuple k and v. A tuple is an element of index 0 in this list (and also the only element in general). Therefore you need to go like

 for k, v in [x.items()[0] for x in lst]: print(k, v) 
0
source share

You can iterate over a key, a pair of dictionary values ​​as follows: -

 for k, v in dic.items(): print(k, v) 

what the code above does is first convert the dictionary to a list of tuples, which are then unpacked one by one, iterating into k, v as well: -

 k, v = (k, v) # Tuple unpacking. 

Now in your case, consider this code: -

 z = [x.items() for x in lst] print(z) 

Exit

 [dict_items([('key1', 1)]), dict_items([('key2', 2)]), dict_items([('key3', 3)])] 

ie list of tuple lists.

So, we rewrite your code as: -

 for k, v in z: print(k, v) 

Where z is a list of tuple lists. At each iteration, it selects a list (which contains only one item) from the parent list, and then tries: -

 k, v = [(key, value)] # a list of only one tuple to be unpacked against two variables and hence the failure. 

Hope this was helpful.

0
source share

All Articles