【问题标题】:multiple key value pairs in dict comprehensiondict理解中的多个键值对
【发布时间】:2014-07-21 22:38:59
【问题描述】:

我正在尝试在这样的 dict 理解中创建多个 key : value 对:

{'ID': (e[0]), 'post_author': (e[1]) for e in wp_users}

我收到"missing ','"

我也试过这样:

[{'ID': (e[0]), 'post_author': (e[1])} for e in wp_users]

然后我收到"list indices must be integers, not str"

我了解,但不确定纠正此问题的最佳方法以及是否可以使用 dict 理解多个 key : value 对?

【问题讨论】:

  • 第二种方法对我来说很好。 wp_users是什么类型的?
  • e[0] 周围的括号在这里没用
  • 当我尝试访问 'post_author' 例如:wp_users_list['post_author'] 是当我得到 "list indices must be integers, not str"
  • 因为您正在创建一个列表而不是第二个选项的字典。尝试遍历它,或wp_users_list[0]['post_author']

标签: python dictionary dictionary-comprehension


【解决方案1】:

字典推导式每次迭代只能产生 一个 键值对。诀窍是产生一个额外的循环来分离这些对:

{k: v for e in wp_users for k, v in zip(('ID', 'post_author'), e)}

这相当于:

result = {}
for e in wp_users:
    for k, v in zip(('ID', 'post_author'), e):
        result[k] = v

请注意,这只是在您的每个 wp_users 列表中重复两个键,因此您会不断地用新值替换相同的键!在这种情况下,您不妨只取最后一个条目:

result = dict(zip(('ID', 'post_author'), wp_users[-1]))

您没有分享您预期的输出

如果想法是有一个字典列表,每个字典都有两个键,那么您希望将上述表达式的列表理解应用于每个 wp_users 条目:

result = [dict(zip(('ID', 'post_author'), e)) for e in wp_users]

这会产生与您自己的第二次尝试相同的输出,但现在您有一个 list 字典。您必须使用整数索引来访问其中一个字典对象或使用更多循环。

【讨论】:

    【解决方案2】:

    我偶然遇到了这个老问题,我不相信接受的答案。

    接受的答案

    接受的答案有什么令人不安的地方?考虑一下:

    >>> wp_users = [(1, 'Bill'), (2, 'Bob')]
    >>> {k: v for e in wp_users for k, v in zip(('ID', 'post_author'), e)}
    {'ID': 2, 'post_author': 'Bob'}
    
    • 第一次迭代wp_users,e = (1, 'Bill'),字典是{'ID':1, 'post_author': 'Bill'}
    • 第二次迭代wp_userse = (2, 'Bob'),字典被完全覆盖到{'ID':2, 'post_author': 'Bob'}

    在每次迭代中,字典的所有值都会被覆盖。可以避免循环,直接跳转到wp_users的最后一个元素:

    >>> {k: v for e in wp_users for k, v in zip(('ID', 'post_author'), e)}
    {'ID': 2, 'post_author': 'Bob'}
    

    或者:

    >>> dict(zip(('ID', 'post_author'), wp_users[-1]))
    {'ID': 2, 'post_author': 'Bob'}
    

    我认为这不是你想要的。

    您想要实现的目标仍不清楚,但我看到了两个选项:您有一个用户列表 (id, post_author),并且您想要创建一个字典列表(每个用户一个字典)或一个元组字典(一个每个字段的元组)。您可以将第一个版本视为按行表示,而将第二个版本视为按相同数据的列表示。

    字典列表

    试试这个:

    >>> [dict(zip(('ID', 'post_author'), user)) for user in wp_users]
    [{'ID': 1, 'post_author': 'Bill'}, {'ID': 2, 'post_author': 'Bob'}]
    

    对于每个userzip 将创建元组('ID', id)('post_author', author)dict 将生成字典。现在您可以访问这样的字段:

    >>> ds = [dict(zip(('ID', 'post_author'), user)) for user in wp_users]
    >>> ds[0]['post_author']
    'Bill'
    

    元组字典

    这更不寻常,但您可能想要一本其值为元组的字典:

    >>> dict(zip(('ID', 'post_author'), zip(*wp_users)))
    {'ID': (1, 2), 'post_author': ('Bill', 'Bob')}
    

    zip(*wp_users) 只是创建了一个元组列表[(id1, id2, ...), (post_author1, post_author2, ...)],其余的与之前的版本类似。

    >>> d = dict(zip(('ID', 'post_author'), zip(*wp_users)))
    >>> d['post_author'][0]
    'Bill'
    

    奖金

    从行视图中提取一列:

    >>> [d['ID'] for d in ds]
    [1, 2]
    

    从列视图中提取一行:

    >>> {k:vs[1] for k, vs in d.items()}
    {'ID': 2, 'post_author': 'Bob'}
    

    【讨论】:

    • 看,这就是缺少正确minimal reproducible example 的问题的问题所在,您并不总是会看到输入对他们的要求没有意义。确实远不清楚它是预期输出的 OP。
    【解决方案3】:

    我认为您的问题是第二个版本正在创建一个 list 字典,而不仅仅是 一个 字典。您正在尝试使用字符串访问列表,这会引发错误:

    >>> obj = [{'data1': 67, 'data2': 78}]
    >>> obj[0]['data1']
    67
    >>> obj['data1']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: list indices must be integers, not str
    >>> 
    

    相反,只需以 `wp_list[0]['post_author'] 访问第二个版本,它应该可以正常工作:

    >>> wp_users = ('Bob', 'Joe', 'Sally')
    >>> wp_list = [{'ID': (e[0]), 'post_author': (e[1])} for e in wp_users]
    >>> wp_list[0]['post_author']
    'o'
    >>> wp_list[1]['post_author']
    'o'
    >>> wp_list[2]['post_author']
    'a'
    >>> 
    

    【讨论】:

      猜你喜欢
      • 2016-03-26
      • 1970-01-01
      • 2021-12-15
      • 2019-06-27
      • 2023-03-23
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多