如何通过键将一堆列表分组到Python中的单个字典中

时间:2017-08-27 19:18:28

标签: python arrays dictionary grouping

我有一堆列表包含彼此相关的元素,我想将它们转换为单个字典,列表为值:

list1 = ['cat', 'animal']
list2 = ['dog', 'animal']
list3 = ['crow', 'bird']

result = {'animal': ['cat', 'dog'], 'bird': 'crow'}

我怎么能这样做?

7 个答案:

答案 0 :(得分:2)

简单方法:

data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]

result = {}

for value, key in data:
    result[key] = result.get(key, []) + [value]

result #=> {'bird': ['crow'], 'animal': ['cat', 'dog']}

使用defaultdict

from collections import defaultdict

data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]

result = defaultdict(list)

for value, key in data:
    result[key].append(value)

result #=> defaultdict(<class 'list'>, {'animal': ['cat', 'dog'], 'bird': ['crow']})

使用groupby中的itertools

from itertools import groupby

data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]

{k: [x[0] for x in g] for k, g in groupby(data, lambda x: x[1])}
#=> {'bird': ['crow'], 'animal': ['cat', 'dog']}

使用reduce中的functools

from functools import reduce

data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]

reduce(lambda a, e: dict(a, **{e[1]: a.get(e[1], []) + [e[0]]}), data, {})
#=> {'bird': ['crow'], 'animal': ['cat', 'dog']}

答案 1 :(得分:1)

如果您有要转换的列表列表,则可以执行以下操作:

dict1 = {}
for li in lists:

   if(li[1] not in dict1):
      dict1[li[1]] = []

   dict1[li1].append(li[0])

请注意,这会产生dict1={'animal':['cat','dog'],'bird':['crow']}而不是dict1={'animal':['cat','dog'],'bird':'crow'},这就是您在问题中所拥有的。

答案 2 :(得分:1)

您可以使用defaultdict模块中的collections。它是标准库的一部分,与字典的操作相同,只是如果传递新密钥,它将自动创建一个新值(在这种情况下为列表)

list1=['cat','animal']
list2=['dog','animal']
list3=['crow','bird']


from collections import defaultdict

# create a new dictionary where an unknown key will automatically
# add the key to the dictionary with a empty list as the value
d = defaultdict(list)

# iterate over your lists, updating the dictionary
for value, key in (list1, list2, list3):
    d[key].append(value)

d
# returns:
defaultdict(list, {'animal': ['cat', 'dog'], 'bird': ['crow']})

答案 3 :(得分:1)

鉴于您的列表包含第一项为值且第二项为键的对,您可以使用由列表构造的defaultdict,然后只追加结果。

from collections import defaultdict

dd = defaultdict(list)
my_lists = [list1, list2, list3]
for my_paired_list in my_lists:
    v, k = my_paired_list
    dd[k].append(v)
>>> dict(dd)
{'animal': ['cat', 'dog'], 'bird': ['crow']}

如果您不希望只有一个元素的键位于列表中(例如'bird': ['crow']应该是'bird': 'crow'),那么只需转换结果:

new_result = {k: v[0] if len(v) == 1 else v for k, v in dd.iteritems()}
>>> new_result
{'animal': ['cat', 'dog'], 'bird': 'crow'}

答案 4 :(得分:1)

如果您有小组列表或小册子后面的列表将是合适的。如果已经使用列表定义了变量,则可以先将所有列表添加到一个变量中,然后使用下面编写的算法对其进行处理。

lists = ['cat','animal'],['dog','animal'],['crow','bird']
results = {}

for list in lists:
    if list[1] in results:
        results[list[1]].append(list[0])
        print('bingo')
    else:
        results[list[1]] = [list[0]]

print(results)

答案 5 :(得分:1)

使用defaultdict的其他答案与您的预期输出不完全匹配。这是一个没有defaultdict的版本。

list1=['cat','animal']
list2=['dog','animal']
list3=['crow','bird']

dict1 = {}
for v, k in (list1, list2, list3):
    if k in dict1:
        # If the value already exists (as string), convert it to list
        # and append the new value
        dict1[k] = [dict1[k]]
        dict1[k].append(v)
    else:
        # Otherwise, we just want a string, not list
        dict1[k] = v

print(dict1)
{'animal': ['cat', 'dog'], 'bird': 'crow'}

答案 6 :(得分:1)

您只能迭代嵌套的原始数据列表,并使用OrderedDict来保留输入顺序:

from collections import OrderedDict

data = [
  ['cat', 'animal'],
  ['dog', 'animal'],
  ['crow', 'bird']
]

d = OrderedDict()

for name, type in data:
   if type in d:
      d[type].append(name)
   else:
      d[type] = [name]

输出:

OrderedDict([('animal', ['cat', 'dog']), ('bird', ['crow'])])