【问题标题】:Transforming dictionary with lists of tuples to lists将带有元组列表的字典转换为列表
【发布时间】:2016-05-20 00:24:50
【问题描述】:

假设我有一本具有这种结构的字典:

namedict = {
1880: 
    [('Mary', 'F', '7065', 1), 
     ('Anna', 'F', '2604', 2), 
     ('John', 'M', '9655', 1)],
1881: 
    [('Mary', 'F', '8065', 1), 
     ('Anna', 'F', '9604', 2), 
     ('John', 'M', '5655', 1)],
1882: 
    [('Mary', 'F', '9065', 1), 
     ('Anna', 'F', '9604', 2), 
     ('John', 'M', '5655', 1)]
    }

我想转换字典,以便数据在以下列表结构中:

[{(Mary, F): {1880: [7065, 1], 1881: [8065, 1], 1882: [9065, 1]}]
[{(Anna, F): {1880: [2064, 2], 1881: [9604, 2], 1882: [9604, 1]}]...

关于我将如何做到这一点的任何建议?

【问题讨论】:

  • 我是否正确理解这一点,即新结构是一个字典列表,其中每个用户/性别对是一个值的键,该值是年份和其他数据的字典?根据你写的python,有一堆单独的列表,或者我看错了。
  • @Wilbur,我正在寻找的新结构是一堆单独的列表,即每个唯一的用户/性别对都应该有自己的列表。谢谢!
  • 我发布了一个我认为符合您要求的答案。如果不是,请告诉我,我很乐意换个思路或解释我的想法。

标签: python list python-3.x dictionary tuples


【解决方案1】:

据我了解,collections.defaultdict() 在这种情况下可以提供帮助:

from collections import defaultdict
from pprint import pprint

namedict = {
    1880:
        [('Mary', 'F', '7065', 1),
         ('Anna', 'F', '2604', 2),
         ('John', 'M', '9655', 1)],
    1881:
        [('Mary', 'F', '8065', 1),
         ('Anna', 'F', '9604', 2),
         ('John', 'M', '5655', 1)],
    1882:
        [('Mary', 'F', '9065', 1),
         ('Anna', 'F', '9604', 2),
         ('John', 'M', '5655', 1)]
}

d = defaultdict(dict)
for key, values in namedict.items():
    for name, gender, value1, value2 in values:
        d[(name, gender)][key] = [value1, value2]

pprint(dict(d))

打印:

{('Anna', 'F'): {1880: ['2604', 2], 1881: ['9604', 2], 1882: ['9604', 2]},
 ('John', 'M'): {1880: ['9655', 1], 1881: ['5655', 1], 1882: ['5655', 1]},
 ('Mary', 'F'): {1880: ['7065', 1], 1881: ['8065', 1], 1882: ['9065', 1]}}

或者,对于 Python3,您可以使用 extended iterable unpacking 并使解决方案更加通用:

d = defaultdict(dict)
for key, values in namedict.items():
    for name, gender, *values in values:
        d[(name, gender)][key] = values

【讨论】:

    【解决方案2】:

    根据我对问题的理解,以下代码应该可以工作。它使用了一个 defaultdict(我最近开始使用更多的东西,但也值得注意的是有 another answer 也在使用它)

    from collections import defaultdict
    def reorder_namedict(namedict):
        new_list_representation = defaultdict(dict)
        for year in namedict:
            for user_tuple in namedict[year]:
                # tuple unpacking has changed based on what version of python is used.
                # I ran this against 3.4.3 and 2.7.6.
                # Use python --version to check if you don't know your version
                name, gender, num1, num2 = user_tuple
                new_list_representation[str((name, gender,))][year] = [int(num1), int(num2)]
    
        new_list = []
    
        # sorted so that it comes out in consistent order for string matching
        for key in sorted(new_list_representation):
            new_list.append([{key: new_list_representation[key]}])
    
        return new_list
    

    代码返回一个列表列表以匹配问题中的第二个代码块。以下输入来自问题(加上或减去一些格式)和预期输出(来自问题,稍作修改以返回所需列表的列表,而不是尝试返回多个列表。

    namedict = {
    1880: 
    [('Mary', 'F', '7065', 1), 
    ('Anna', 'F', '2604', 2), 
    ('John', 'M', '9655', 1)],
    1881: 
    [('Mary', 'F', '8065', 1), 
    ('Anna', 'F', '9604', 2), 
    ('John', 'M', '5655', 1)],
    1882: 
    [('Mary', 'F', '9065', 1), 
    ('Anna', 'F', '9604', 2), 
    ('John', 'M', '5655', 1)]
    }
    
    output_to_match = [
    [{str(('Anna', 'F',)): {1880: [2604, 2], 1881: [9604, 2], 1882: [9604, 2],}}],
    [{str(('John', 'M',)): {1880: [9655, 1], 1881: [5655, 1], 1882: [5655, 1],}}],
    [{str(('Mary', 'F',)): {1880: [7065, 1], 1881: [8065, 1], 1882: [9065, 1],}}],
    ]
    

    下面的代码将证明这两个列表是相同的。您可以取消注释显示每个列表以及如何将其转换为字符串的打印语句,但我发现让代码检查每个字符是否匹配更可靠(我自己错过了一些小错误)。

    match_this = str(output_to_match)
    iTried = str(reorder_namedict(namedict))
    # print(match_this)
    # print('---')
    # print(iTried)
    for i in range(0, len(match_this)):
        if not match_this[i] == iTried[i]:
            print('%d %s %s' % (i, match_this[i], iTried[i],))
    print(match_this == iTried)
    

    【讨论】:

      猜你喜欢
      • 2020-02-25
      • 2013-04-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      • 2017-06-07
      相关资源
      最近更新 更多