Given a flat list of simple dictionaries
lst = [{'key1': 1}, {'key2': 2}, {'key3': 3}]
I'd like to find the dict that yields the minimum value evaluated using a method not detailed here. My first idea was to iterate the list to check dict by dict, but this fails:
for k, v in [x.items() for x in lst]:
print(k, v)
results ValueError (as well as using a generator instead of the list):
for k, v in [x.items() for x in lst]:
ValueError: not enough values to unpack (expected 2, got 1)
However,
for x in lst:
for k, v in x.items():
print(k, v)
yields
key1 1
key2 2
key3 3
As expected. I assume all approaches work as intended (unless PEBKAC), but why doesn't it work using the list comprehension? Could someone enlighten me?
Edit: I use python 3 and I know items() yields a dict_view but I don't see why the logic doesn't work.
You're missing a level of iteration.
Normally, dicts have 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 just one item, but the result of items()
is still a tuple of tuples.
If you print the result of [x.items() for x in lst]
you'll see that the result is a list of dict_view
items; each one of those can itself be iterated.
Instead of taking the first element of your dict_view
you can add one level of indentation (as @DanielRoseman suggested) in your list comprehension:
for k, v in [(k, v) for x in lst for (k, v) in x.items()]:
print(k, v)
yield
key1 1
key2 2
key3 3
as expected.
Try to unpack your lst
step by step to understand how it is constructed.
>>> in: lst[0].items()
>>> out: [('key1', 1)]
Your result (that is equal to your x.items()
expression in the list comprehension) is another list containing your tuple of k and v. The tuple is the element of index 0 in this list (and also the only element at all). So you need to go like
for k, v in [x.items()[0] for x in lst]:
print(k, v)
You can iterate over key, value pair of a dictionary like this:-
for k, v in dic.items():
print(k, v)
what above code does is to first convert dictionary into a list of tuples which are then unpacked one by one while iterating into k, v just like:-
k, v = (k, v) # Tuple unpacking.
Now in your case, Consider this code:-
z = [x.items() for x in lst]
print(z)
Output is
[dict_items([('key1', 1)]), dict_items([('key2', 2)]), dict_items([('key3', 3)])]
ie a list of lists of tuple.
So, Let us rewrite your code as :-
for k, v in z:
print(k, v)
Where z is a list of lists of tuple. At each iteration, it picks up a list(which contains only one element) from the parent list and then it tries:-
k, v = [(key, value)] # a list of only one tuple to be unpacked against two variables and hence the failure.
I hope this was helpful.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.