简体   繁体   English

使用Python中的词典列表创建新词典

[英]Creating a new dictionary from a list of dictionaries in Python

I have a list of dictionaries, where some values are strings, and other values are integers: 我有一个字典列表,其中一些值是字符串,而其他值是整数:

list_countries = [{'country' : 'Suriname', 
            'population' : 532724,
            'capital': 'Paramaribo', 
            'anthem': 'God zij met ons Suriname'},
            {'country' : 'Sweden', 
            'population' : 9683248,
            'capital': 'Stockholm', 
            'anthem': 'Du gamla, Du fria'},
             ...]

I would like to reshape each of these key-value pairs into one big new dictionary. 我想将每个键值对重塑为一个新的大词典。 However, my approach has issues: 但是,我的方法存在以下问题:

dict_countries = { 'countries':       [],
                   'pop':             [],
                   'capital_city':    [],
                   'national_anthem': [] }

I then iterate through and append all values with .extend() . 然后,我遍历并使用.extend()附加所有值。

for dictionary in list_countries:
    dict_countries['countries'].extend(dictionary['country'])
    dict_countries['pop'].extend(dictionary['population'])
    dict_countries['capital_city'].extend(dictionary['capital'])
    dict_countries['national_anthem'].extend(dictionary['anthem'])

However, this doesn't work. 但是,这不起作用。 All strings are broken up, letter by letter. 所有的字符串都一个字母一个字母地分解。 For the integers, I get the error: 对于整数,我得到了错误:

TypeError: 'int' object is not iterable

What is the correct approach to do this? 这样做的正确方法是什么?

EDIT: I believe there is a value for each key. 编辑:我相信每个键都有一个值。 However, let's say there isn't. 但是,可以说没有。 How would I rewrite the above in order to add NaN if there is no value found. 如果找不到值,我将如何重写以上内容以添加NaN

.extend() expects the argument passed to it to be an iterable, ie. .extend()期望传递给它的参数是可迭代的,即。 a list or a string etc. As per your example, population is an integer and therefore not iterable hence your exception message. 根据您的示例, population是一个整数,因此不可迭代,因此出现异常消息。

If you change it to .append() it will behave as you expect it to. 如果将其更改为.append() ,则其行为将与您期望的一样。

The reason you are getting the output you are is because there is a difference between append and extend on a list. 获得输出的原因是因为在列表上appendextend之间存在差异。 If you extend with an iterable as a parameter (which a string is) it would inline each item of the iterable into the dict (which is each letter for the string). 如果使用Iterable作为参数(字符串是) extend ,它将把Iterable的每个项目内联到dict(字符串的每个字母)中。 However it fails for the int as that is not an iterable. 但是,它对于int来说是失败的,因为它不是可迭代的。 I would prefer to use append which simply appends to the list in the dict. 我宁愿用append其中就追加到在字典列表中。

list_countries = [{'country' : 'Suriname', 
            'population' : 532724,
            'capital': 'Paramaribo', 
            'anthem': 'God zij met ons Suriname'},
            {'country' : 'Sweden', 
            'population' : 9683248,
            'capital': 'Stockholm', 
            'anthem': 'Du gamla, Du fria'}]

dict_countries = { 'countries':       [],
                   'pop':             [],
                   'capital_city':    [],
                   'national_anthem': [] }

for dictionary in list_countries:
    dict_countries['countries'].append(dictionary['country'])
    dict_countries['pop'].append(dictionary['population'])
    dict_countries['capital_city'].append(dictionary['capital'])
    dict_countries['national_anthem'].append(dictionary['anthem'])

print dict_countries

You have two problems to solve here: 您有两个问题需要解决:
Build lists of the values from your dictionaries and translate the old keys to their new names. 从字典中构建值列表,然后将旧键转换为新名称。

Use the setdefault method of the builtin dictionary and use a translation-dictionary as a dictionary in the literal sense (ie for translation). 使用内置词典的setdefault方法,并将翻译词典用作字面意义上的词典(即用于翻译)。

Set up the translations like this: 像这样设置翻译:

>>> translations = {'country': 'countries',
...                 'population': 'pop',
...                 'capital': 'capital_city',
...                 'anthem': 'national_anthem'}

Then build your new dictionary: 然后建立您的新字典:

>>> merged = {}
>>> for d in list_countries:
...     for k in d:
...         key = translations.get(k, k)
...         merged.setdefault(key, []).append(d[k])
... 
>>> merged
{'national_anthem': ['God zij met ons Suriname', 'Du gamla, Du fria'], 'capital_city': ['Paramaribo', 'Stockholm'], 'pop': [532724, 9683248], 'countries': ['Suriname', 'Sweden']}

... and if you can be sure all dictionaries share the same keys, here's a oneliner: ...并且如果您可以确定所有词典都共享相同的键,则这是一个单行代码:

>>> {translations.get(k,k):[d[k] for d in list_countries] for k in list_countries[0].keys()}
{'national_anthem': ['God zij met ons Suriname', 'Du gamla, Du fria'], 'capital_city': ['Paramaribo', 'Stockholm'], 'pop': [532724, 9683248], 'countries': ['Suriname', 'Sweden']}

Here's what I've done. 这就是我所做的。 The only limitation is that the keys in the new dictionary are not grammatically pluralised but I guess you can do that manually at the end. 唯一的限制是新字典中的键不是语法上复数的,但是我想您可以在最后手动进行。

list_countries = [{'country' : 'Suriname', 
            'population' : 532724,
            'capital': 'Paramaribo', 
            'anthem': 'God zij met ons Suriname'},
            {'country' : 'Sweden', 
            'population' : 9683248,
            'capital': 'Stockholm', 
            'anthem': 'Du gamla, Du fria'},
             ]


from collections import defaultdict
d = defaultdict(list)
for i in list_countries:
   for k,v in i.items():
     d[k].append(v)

The d can be coverted back into a regular dict easily. d可以轻松地转换为常规dict

keys =  list_countries[0].keys()
values = (list(t) for t in zip(*[d.values() for d in list_countries]))
dict(zip(keys, values))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM