magic.mrr
magic.mrr

Reputation: 25

Iterating over dictionary keys in order?

I am trying to iterate over a dictionary (inside another dictionary specifically, but I don't think that part matters), and I'm unable to get the for loop to iterate over the values in the order that they were placed in. I would like to be able to take the first value of each dictionary. I thought that after python 3.6, dictionaries kept their order (here), but these wont stay in order.

This is what my dictionary looks like:

count_dict = {'dessert': Counter({'cake': 1}), 'vegetable': Counter({'carrots': 1, 'beet': 1}), 'grain': Counter({'wheat': 3, 'rice': 2, 'zantham': 1}), 'meat': Counter({'chicken': 2, 'pork': 1})}

This is my code that tried:

for it in count_dict:
        for food in count_dict[it]:
            out_dict[it] = food
return(out_dict)

I get:

{'dessert': 'cake', 'vegetable': 'beet', 'grain': 'rice', 'meat': 'chicken'}

but need to get the first value from each dictionary:

{'dessert': 'cake', 'vegetable': 'carrots', 'grain': 'wheat', 'meat': 'chicken'}

I looked for ever for an answer on Stack but couldn't find an answer. (sorry if the answers obvious, I'm kinda new to Python)

Upvotes: 2

Views: 1020

Answers (2)

Omar AlSuwaidi
Omar AlSuwaidi

Reputation: 1404

If you strictly want to return the first key value only, regardless of alphabetical key order or numerical value order, you could simply do the following:

from collections import Counter

count_dict = {'dessert': Counter({'cake': 1}), 'vegetable': Counter({'carrots': 1, 'beet': 1}), 'grain': Counter({'wheat': 3, 'rice': 2, 'zantham': 1}), 'meat': Counter({'chicken': 2, 'pork': 1})}
out_dict = {}

for it in count_dict:
        for food in count_dict[it]:
            out_dict[it] = food
            break  # Break out the loop so that you only iterate over the first key in dictionary
print(out_dict)

Upvotes: 0

nobleknight
nobleknight

Reputation: 797

Dictionaries (after python 3.6) maintain their insertion order (order in which keys and values are inserted), not the sorted order.


I did get an answer.

from collections import Counter

count_dict = {'dessert': Counter({'cake': 1}), 'vegetable': Counter({'carrots': 1, 'beet': 1}), 'grain': Counter({'wheat': 3, 'rice': 2, 'zantham': 1}), 'meat': Counter({'chicken': 2, 'pork': 1})}

new_dict = {}

for a, b in count_dict.items():
    new_dict[a] = sorted(b, key=lambda x: (-b[x], x))[0]

print(new_dict)

This will sort inner dictionary first by the values then alphabetically by keys.

sorted(b, key=lambda x: (-b[x], x))

Sample Run 1 (sorting alphabetically, because values are same.)

b = {'carrots': 1, 'beet': 1}
sorted(b, key=lambda x: (-b[x], x))

Output

['beet', 'carrots']

Sample Run 2 (sorting by value an the alphabetically.)

b = {'wheat': 3, 'rice': 2, 'zantham': 1}
sorted(b, key=lambda x: (-b[x], x))

Output

['wheat', 'rice', 'zantham']

Upvotes: 1

Related Questions