开发者

How would I merged nested dictionaries in a list in python?

开发者 https://www.devze.com 2022-12-27 05:00 出处:网络
for example if i had the result [{\'Germany\': {\"Luge - Men\'s Singles\": \'Gold\'}}, {\'Germany\': {\"Luge - Men\'s Singles\": \'Silver\'}},

for example if i had the result

[{'Germany': {"Luge - Men's Singles": 'Gold'}}, 
{'Germany': {"Luge - Men's Singles": 'Silver'}},
{'Italy': {"Luge - Men's Singles": 'Bronze'}}]
[{'Germany': {"Luge - Women's Singles": 'Gold'}},
{'Austria': {"Luge - Women's Singles": 'Silver'}},
{'Germany': {"Luge - Women's Singles": 'Bronze'}}]
[{'Austria': {'Luge - Doubles': 'Gold'}}, 
{'Latvia': {'Luge - Doubles': 'Silver'}},
{'Germany': {'Luge - Doubles': 'Bronze'}}]

how would I sort this so that all of the events germany and so on had won could be under one single title. i.e germany would be germany:Luge - Men's Singles: Gold, Silver, Luge - Women's Singles: Gold, Bronze, Luge - Doubles: Bronze.

thanks for any help

EDIT: this is a straight copy and paste from the python shell now to help confusion:

[{'Germany': {"Luge - Men's Singles": 'Gold'}}, {'Germany': {"Luge - Men's Singles": 'Silver'}}, {'Italy': {"Luge - Men's Singles": 'Bronze'}}] [{'Germany': {"Luge - Women's Singles": 'Gold'}}, {'Austria': {"Luge - Women's Singles": 'Silver'}}, {'Germany': {"Luge - Women's Singles": 'Bronze'}}] [{'Austria': {'Luge - Doubles': 'Gold'}}, {'Latvia': {'Luge - Doubles': 'Silver'}}, {'Germany': {'Luge - Doubles': 开发者_StackOverflow'Bronze'}}]

sorry about that im new to this site. It loops round 3 time one for each different event and i was wondering if i could get the desired from merging it after the final loop?


import collections

merged_result = collections.defaultdict(list)

for L in listoflistsofdicts:
  for d in L:
    for k in d:
      merged_result[k].append(d[k])

or if you just have a list of dicts instead of a list of lists of dicts (hard to say from your Q!-), then just the

  for d in listofdicts:
    for k in d:
      merged_result[k].append(d[k])

part of the loop.

If you want strings rather than lists as the values of merged_result then after the above code add

for k in merged_result:
    merged_result[k] = ', '.join(merged_result[k])

or, equivalently (but building a new plain dict instead of the defaultdict):

merged_result = dict((k, ', '.join(v)) for k, v in merged_result.iteritems())

(this assumes Python 2.* -- in Python 3, use .items instead of .iteritems).

Edit: looking at the sample code it looks like it's invalid syntax for a list of list of dicts (missing commas) so I showed how to deal with that, too.


(Sorry, I really meant this as a comment on Alex Martelli's answer, since mine is based on his; but when I originally posted I didn't have enough reputation to comment)

Alex's answer doesn't actually generate the intended result. I don't mean the finer points of having a list of lists of dicts, or the lack of commas between the lists (more on that later). But the original question wanted, as a result, a compilation of all medals by country, by competition. Alex's solution will answer:

> 'Germany': [{"Luge - Men's Singles": 'Gold'},
             {"Luge - Men's Singles": 'Silver'},
             {"Luge - Women's Singles": 'Gold'},
             {"Luge - Women's Singles": 'Bronze'},
             {'Luge - Doubles': 'Bronze'}]

But I believe the original question actually asked for:

> 'Germany': [{"Luge - Men's Singles": ['Gold', 'Silver']},
             {"Luge - Women's Singles": ['Gold', 'Bronze'},
             {'Luge - Doubles': 'Bronze'}]

The data in the question is a bit confusing, I see two possibilities:

1) The data shown is actually three different examples, and the task is to merge dict entries within each list, separately. That is, given

[{'Germany': {"Luge - Men's Singles": 'Gold'}}, 
{'Germany': {"Luge - Men's Singles": 'Silver'}},
{'Italy': {"Luge - Men's Singles": 'Bronze'}}]

you want

['Germany': {"Luge - Men's Singles": ['Gold', 'Silver'],
             "Luge - Women's Singles": ['Gold', 'Bronze']},
 'Italy': {"Luge - Men's Singles": ['Bronze']}]

, given

[{'Germany': {"Luge - Women's Singles": 'Gold'}},
{'Austria': {"Luge - Women's Singles": 'Silver'}},
{'Germany': {"Luge - Women's Singles": 'Bronze'}}]

you want

['Germany': {"Luge - Women's Singles": ['Gold', 'Bronze']},
 'Austria': {"Luge - Women's Singles": ['Silver']}]

and so on. I gather this is the most likely interpretation of the question.

The following code does that:

from collections import defaultdict

merged = defaultdict(lambda: defaultdict(list))
for d in list_of_dicts:
    for k in d:
        for competition, medal in d[k].iteritems():
            merged[k][competition].append(medal)

Running this for the first of the lists shown above, you get

defaultdict(<function <lambda> at 0x1907db0>,
 {'Italy': defaultdict(<type 'list'>, {"Luge - Men's Singles": ['Bronze']}),
  'Germany': defaultdict(<type 'list'>, {"Luge - Men's Singles": ['Gold', 'Silver']})})

2) The second possibility is that the data in the question is one single list, containing 3 lists, each of these containing dicts. I think this is not what the original question means, but, since I'd already written the code for that, here it is :)

from collections import defaultdict

merged = defaultdict(lambda: defaultdict(list))
for L in listoflistsofdicts:
  for d in L:
    for k in d:
      for competition, medal in d[k].iteritems():
          merged[k][competition].append(medal)

Running the code above for the lists shown on the question (with the necessary commas added, you get:

 defaultdict(<function <lambda> at 0x1904b70>,
    {'Italy': defaultdict(<type 'list'>, {"Luge - Men's Singles": ['Bronze']}),
     'Austria': defaultdict(<type 'list'>, {'Luge - Doubles': ['Gold'],
                                            "Luge - Women's Singles": ['Silver']}),
     'Latvia': defaultdict(<type 'list'>, {'Luge - Doubles': ['Silver']}),
     'Germany': defaultdict(<type 'list'>, {'Luge - Doubles': ['Bronze'],
                                            "Luge - Men's Singles": ['Gold', 'Silver'],
                                            "Luge - Women's Singles": ['Gold', 'Bronze']})
    })

Please note that both of these codes don't sort medal types (i.e., you might end up with ['Gold', 'Silver'] or ['Silver', 'Gold']).

Of course, if you get separated lists as used in solution 1), but need a merge of all of them, simply bring them all together in a list, and use solution 2).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号