简体   繁体   English

嵌套字典的元组列表,不覆盖

[英]List of tuples to nested dictionary without overriding

I need to convert the above list of tuples to nested dictionary without overwriting the value as below in python 我需要将上述元组列表转换为嵌套字典,而不会覆盖python中的以下值

[('a', '1'),
  ('b', 'true'),
  ('b', 'none'),
  ('a', '2'),
  ('b', 'true'),
  ('a', '3'),
  ('b', 'false')]


{'a': {'1' : { 'b' : ('true','none')},
       '2' : { 'b' : ('true')},
       '3' : { 'b' : ('false')}}}

Converting each tuple into dictionary using 使用以下命令将每个元组转换为字典

dict()

and merging the dictionary doesn't work. 并且合并字典不起作用。 Is there any pythonic way to do this? 有什么pythonic方法可以做到这一点吗?

Here's one way to do it with collections.defaultdict : 这是使用collections.defaultdict做到这一点的一种方法:

from collections import defaultdict
import pprint

data = [('a', '1'), ('b', 'true'), ('b', 'none'), ('a', '2'), ('b', 'true'), ('a', '3'), ('b', 'false')]

d = defaultdict(lambda: defaultdict(lambda: defaultdict(tuple)))    
for i, j in data:
    if i == 'a':
        p = d[i][j]
    else:
        p[i] += j,

pprint.pprint(d)
# {'a': {'1': defaultdict(<class 'tuple'>, {'b': ('true', 'none')}),
#        '2': defaultdict(<class 'tuple'>, {'b': ('true',)}),
#        '3': defaultdict(<class 'tuple'>, {'b': ('false',)})}}

You could also use the dictionary's setdefault method to return default values for new keys, although the defaultdict approach is much cleaner and faster: 您也可以使用字典的setdefault方法返回新键的默认值,尽管defaultdict方法更加defaultdict快捷:

c = {}
for i, j in data:
    if i == 'a':
        q = c.setdefault(i, {}).setdefault(j, {})
    else:
        q[i] = q.setdefault(i, ()) + (j,)

pprint.pprint(c)
# {'a': {'1': {'b': ('true', 'none')},
#        '2': {'b': ('true',)},
#        '3': {'b': ('false',)}}}

Expanding @MosesKoledoye answer, if the first value in the dictionary is only 'a' and 'b' , you know that the outer dictionary will always contain at most one element using 'a' as the key and the inner dictionary will always contain at most one element using 'b' as the key. 扩展@MosesKoledoye答案,如果字典中的第一个值仅是'a''b' ,则您会知道外部字典将始终包含最多一个以'a'为键的元素,而内部字典将始终包含在使用'b'作为键的大多数元素。 So in the end you get the same information if it is {'1': ('true', 'none')… . 因此,最后如果它是{'1': ('true', 'none')…您将获得相同的信息。 You can convert that to your format simply by wrapping the data in some dictionaries. 您只需将数据包装在一些字典中即可将其转换为格式。 This means you can do the following 这意味着您可以执行以下操作

output = defaultdict(tuple)
for i, j in data:
    if i == 'a':
        current = j
    else:
        # i == 'b'
        output[current] += (j, )

This will result in the following: 这将导致以下结果:

defaultdict(<type 'tuple'>, {'1': ('true', 'none'), '3': ('false',), '2': ('true',)})

Now to get it into a dictionary like yours you can do the following: 现在,要将其放入像您一样的字典中,您可以执行以下操作:

output = {k: {'b': v} for k, v in output.items()}
if output:
    output = {'a': output}

Resulting in the following: 结果如下:

{'a': {'1': {'b': ('true', 'none')}, '3': {'b': ('false',)}, '2': {'b': ('true',)}}}

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

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