【问题标题】:Iterating over dictionary values which are lists to create a new list of dictionaries迭代作为列表的字典值以创建新的字典列表
【发布时间】:2019-07-28 03:01:41
【问题描述】:

我有一本带有“标题”、“作者”、“出版年份”键的字典,其值是列表:

book_dict= {'Titles': ['Double Play', 'Slow Burn', 'Altman Code'], 'Authors': ['Brown, Dan', 'Hannah, Kristin', 'Neri, Penelope'], 
'Publication Year': [2004, 2003, 2006]}

每个条目在列表中的位置相互对应,因此book_dict['Titles'][0]book_dict['Authors'][0] 是关于同一本书的信息。 (注意:这些是书名和作者的真实姓名,但实际上并不对应)

我想创建一个包含这样的字典的列表:

[{"Title":"Double Play","Author":"Brown, Dan", "Publication Year":2004}, 
{"Title":"Slow Burn","Author":"Hannah, Kristin", "Publication Year":2003},
{"Title":"Altman Code","Author":"Neri, Penelope'", "Publication Year":2006}]

到目前为止,我已经尝试过:

for i in range(30):
    for k,v in book_dict.items():
        print({k[i]:v[i]})

但我得到了这个:

{"Title":"Double Play"}
{"Author":"Brown, Dan"}
{"Publication Year":2004}
{"Title":"Slow Burn"}
{"Author":"Hannah, Kristin"}
{"Publication Year":2003}
{"Title":"Altman Code"}
{"Author":"Neri, Penelope"} 
{"Publication Year":2006}

加上IndexError: list index out of range

【问题讨论】:

    标签: python list dictionary for-loop


    【解决方案1】:

    一种不需要对键进行硬编码的通用方法是迭代 dict 的压缩值并使用压缩值压缩 dict 键以使用 dict 构造函数构建子字典:

    [dict(zip(book_dict, t)) for t in zip(*book_dict.values())]
    

    这会返回:

    [{'Titles': 'Double Play', 'Authors': 'Brown, Dan', 'Publication Year': 2004},
     {'Titles': 'Slow Burn', 'Authors': 'Hannah, Kristin', 'Publication Year': 2003},
     {'Titles': 'Altman Code', 'Authors': 'Neri, Penelope', 'Publication Year': 2006}]
    

    【讨论】:

    • 是的,因为即使在早期版本的 Python 中不保证 dicts 的键顺序,值始终遵循与键相同的顺序,因此压缩键列表和值列表将始终产生始终如一的正确配对。
    • @blhsing 知道为什么dict(zip(book_dict, t)) 足以获取字典键吗? dict(zip(book_dict.keys(), t)) 似乎产生了相同的结果。
    • @MarielleDado 这是因为 dict 对象在用作可迭代对象时,会从生成器中生成其键,因此不需要调用 keys() 方法。请参阅dict's documentationiter(d) 部分。
    • @blhsing 那么t 在每个循环中取什么值?我想我不确定zip(*) 是如何作为可交互对象工作的。
    • @MarielleDado t 的值来自zip(*book_dict.values()) 的输出,它与您的样本输入配对['Double Play', 'Slow Burn', 'Altman Code']['Brown, Dan', 'Hannah, Kristin', 'Neri, Penelope'] 中的每个项目以形成(('Double Play', 'Brown, Dan'), ('Slow Burn', 'Hannah, Kristin'), ('Altman Code', 'Neri, Penelope')) 的序列.需要解压运算符 * 来使 book_dict.values() 中的项目为 zip 提供单独的参数,因为 zip 预计需要几个迭代来进行压缩。
    【解决方案2】:

    您必须在原始字典的值上使用zip 的一些变体:

    >>> [{'Title': t, 'Author': a, 'Publication Year': y} for t, a, y in zip(book_dict['Titles'], book_dict['Authors'], book_dict['Publication Year'])]
    [{'Title': 'Double Play', 'Author': 'Brown, Dan', 'Publication Year': 2004}, 
     {'Title': 'Slow Burn', 'Author': 'Hannah, Kristin', 'Publication Year': 2003}, 
     {'Title': 'Altman Code', 'Author': 'Neri, Penelope', 'P
    ublication Year': 2006}]
    

    您可能会使用一些实用程序使其更具可读性:

    from  operator import itemgetter
    
    items = itemgetter('Titles', 'Authors', 'Publication Year')
    [
        {'Title': t, 'Author': a, 'Publication Year': y} 
        for t, a, y in zip(*items(book_dict))
    ]
    # [{'Title': 'Double Play', 'Author': 'Brown, Dan', 'Publication Year': 2004}, 
    #  {'Title': 'Slow Burn', 'Author': 'Hannah, Kristin', 'Publication Year': 2003}, 
    #  {'Title': 'Altman Code', 'Author': 'Neri, Penelope', 'Publication Year': 2006}]
    

    【讨论】:

      【解决方案3】:

      试试这个:

      [{k : book_dict[k][j] for k in book_dict} for j in range(len(book_dict['Titles']))]
      

      输出

      [{'Titles': 'Double Play', 'Authors': 'Brown, Dan', 'Publication Year': 2004}, {'Titles': 'Slow Burn', 'Authors': 'Hannah, Kristin', 'Publication Year': 2003}, {'Titles': 'Altman Code', 'Authors': 'Neri, Penelope', 'Publication Year': 2006}]
      

      【讨论】:

        【解决方案4】:

        您可以使用zip() 以锁步方式迭代多个列表,例如在

        result = []
        for title, author, year in zip(book_dict['Titles'], book_dict['Authors'],     
        book_dict['Publication Year']):
            result.append({'Title': title, 'Author': author, 'Year': year})
        
        print result
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-01-31
          • 2023-01-02
          • 2021-07-20
          • 1970-01-01
          • 2017-03-25
          • 2022-01-16
          • 1970-01-01
          相关资源
          最近更新 更多