简体   繁体   English

将元组列表转换为具有键的多个dict值的字典

[英]Convert list of tuples to dictionary with multiple dict values for a key

My list of tuples: 我的元组列表:

list = [('WALMART', '601 12th Avenue Northeast',916523), 
('WALMART SHARED', '1953 west brown street',916523)]

Wanted to Convert the list of tuples to Dictionary as shown below: 想要将元组列表转换为Dictionary,如下所示:

dict =
    {
        916523: [{
                'cancmpname': 'WALMART',
                'canaddress': '601 12th Avenue Northeast',
            },
            {
                'cancmpname': 'WALMART SHARED',
                'canaddress': '1953 west brown street',

            },
        ]
    }

My code so far: 我的代码到目前为止:

dict = {}
for result in list:
      dict[result[2]]={}
      dict[result[2]]['cmpname']=result[0]
      dict[result[2]]['cmpaddress']=result[1]

This converts the list into a dictionary with the latest value it doesn't append both the results as dictionary array values 这会将列表转换为具有最新值的字典,但不会将结果作为字典数组值附加

result from my code: 我的代码的结果:

dict =
    {
        916523: {
                'cancmpname': 'WALMART SHARED',
                'canaddress': '1953 west brown street',

            }

    }

You can use itertools.groupby : 你可以使用itertools.groupby

import itertools
l = [('WALMART', '601 12th Avenue Northeast',916523), ('WALMART SHARED', '1953 west brown street',916523)]
final_data = {a:[dict(zip(['cancmpname', 'canaddress'], i[:-1])) for i in b] for a, b in itertools.groupby(l, key=lambda x:x[-1])}

Output: 输出:

{916523: [{'canaddress': '601 12th Avenue Northeast',
       'cancmpname': 'WALMART'},
      {'canaddress': '1953 west brown street',
       'cancmpname': 'WALMART SHARED'}]}

You can use collections.defaultdict for an O(n) solution. 您可以将collections.defaultdict用于O(n)解决方案。

from collections import defaultdict

lst = [('WALMART', '601 12th Avenue Northeast',916523), 
       ('WALMART SHARED', '1953 west brown street',916523)]

d = defaultdict(list)

for name, address, code in lst:
    d[code].append({'cancmpname': name, 'canaddress': address})

Result 结果

defaultdict(list,
            {916523: [{'canaddress': '601 12th Avenue Northeast',
                       'cancmpname': 'WALMART'},
                      {'canaddress': '1953 west brown street',
                       'cancmpname': 'WALMART SHARED'}]})

Explanation 说明

  • Do not name variables after classes, eg use lst instead of list , d instead of dict . 不要将其命名课后变量,如使用lst ,而不是listd ,而不是dict
  • For each item in lst , build a dictionary and append it with key equal to the code. 对于lst每个项目,构建一个字典并使用等于代码的键附加它。

Benchmarking 标杆

lst = [('WALMART', '601 12th Avenue Northeast',916523), 
       ('WALMART SHARED', '1953 west brown street',916523)]

def jpp(lst):
    d = defaultdict(list)
    for name, address, code in lst:
        d[code].append({'cancmpname': name, 'canaddress': address})
    return d

def ajax(l):
    return {a:[dict(zip(['cancmpname', 'canaddress'], i[:-1])) for i in b] for a, b in itertools.groupby(l, key=lambda x:x[-1])}

lst = lst*1000

%timeit jpp(lst)    # 696 µs per loop
%timeit ajax(lst)   # 3.68 ms per loop

Here is a solution which does not use any library, although I think the defaultdict solution is cleanner: 这是一个不使用任何库的解决方案,虽然我认为defaultdict解决方案是cleanner:

li = [('WALMART', '601 12th Avenue Northeast',916523),
('WALMART SHARED', '1953 west brown street',916523)]

d = {}

for name, address, zipcode in li:
    d.setdefault(zipcode, []).append(dict(cancmpname=name, canaddress=address))

A few notes 几点说明

  • Do not use list and dict to name your variables, you effectively overshadow the built-in types 不要使用listdict命名变量,有效地掩盖了内置类型
  • If a key is not in the dictionary, setdefault will create the value (an empty list in this case) and assign to that key 如果某个键不在字典中, setdefault将创建该值(在这种情况下为空列表)并分配给该键
  • If a key already exists in the dictionary, setdefault will do nothing 如果字典中已存在密钥,则setdefault将不执行任何操作
  • In both cases, setdefault will return the value for that key, which I took and append a new dictionary to it. 在这两种情况下, setdefault都会返回该键的值,我将其添加到其中并添加一个新词典。

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

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