如何从字典列表中获取值,这些字典本身包含 Python 中的字典列表
How to get values from a list of dictionaries, which themselves contain lists of dictionaries in Python
我遇到了从包含字典的列表中获取值的问题,其中每个字典都有一个包含字典的列表。听起来很容易做,但我花了一些时间,我认为如果我 post 它会对其他人有用。我的数据示例可以是:
player_info = [{[{'tag': 'tag 1'}]},
{[{'tag': 'tag 2'}]}]
外部列表称为'player_info'。这包含 25 个字典,其中每个字典包含一个列表,其中包含(除其他外)一个名为 'opponent' 的字典,其中包含一个包含字典的列表(是的,非常混乱)。从最里面的字典中,我想要与 'tag' 键关联的值。
我想到了两种方法:
- 创建循环。
for i in range(25):
print(player_info[i]['opponent'][0]['tag'])
- 遍历列表:
{each_dictionary['opponent'][0]['tag'] for each_dictionary in player_info}
我认为第二种方式效率更高。让我知道您的想法,以及是否有更聪明的方法。
首先:dict
要求字典中的每个元素都有一个 key-value 关联。您的第二级数据结构虽然不包含键:({[{'tag': 'tag 1'}]}
) 这是一个 set
。与 dict
不同,set
没有与其元素关联的键。所以你的数据结构看起来像 List[Set[List[Dict[str, str]]]]
.
第二:当我尝试 运行
# python 3.8.8
player_info = [{[{'tag': 'tag 1'}]},
{[{'tag': 'tag 2'}]}]
我收到错误 TypeError: unhashable type: 'list'
。那是因为您的代码试图在集合中包含一个列表。 python 中的集合成员资格要求成员可散列。但是,您不会找到在 list
对象上定义的 __hash__()
函数。即使您通过将 list
替换为 tuple
来解决此问题,您也会发现 dict
对象也不可散列。潜在的解决方案包括使用不可变对象,如 frozendict
或 tuple
,但那是另一个 post.
为了回答您的问题,我已将您的问题重新表述为
player_info = [[[{'tag': 'tag 1'}]],
[[{'tag': 'tag 2'}]]]
并将性能差异与 A) 显式循环进行比较:
for i in range(len(player_info)):
print(player_info[i][0][0]['tag'])
针对 B) 列表理解
[
print(single_player_info[0][0]['tag'])
for single_player_info in player_info
]
运行 jupyter 中的上述代码块与 %%timeit
细胞魔法,我得到:
A) 154 µs ± 14.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
和
B) 120 µs ± 11 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
注意:至少有两个原因导致该实验严重偏斜:
- 我仅使用您提供的数据 (N=2) 测试了这两个试验。我们很可能会观察到与初始条件所建议的不同的缩放行为。
print
消耗大量时间,使这个问题严重受制于内核状态
我希望这能回答你的问题。
我遇到了从包含字典的列表中获取值的问题,其中每个字典都有一个包含字典的列表。听起来很容易做,但我花了一些时间,我认为如果我 post 它会对其他人有用。我的数据示例可以是:
player_info = [{[{'tag': 'tag 1'}]}, {[{'tag': 'tag 2'}]}]
外部列表称为'player_info'。这包含 25 个字典,其中每个字典包含一个列表,其中包含(除其他外)一个名为 'opponent' 的字典,其中包含一个包含字典的列表(是的,非常混乱)。从最里面的字典中,我想要与 'tag' 键关联的值。
我想到了两种方法:
- 创建循环。
for i in range(25): print(player_info[i]['opponent'][0]['tag'])
- 遍历列表:
{each_dictionary['opponent'][0]['tag'] for each_dictionary in player_info}
我认为第二种方式效率更高。让我知道您的想法,以及是否有更聪明的方法。
首先:dict
要求字典中的每个元素都有一个 key-value 关联。您的第二级数据结构虽然不包含键:({[{'tag': 'tag 1'}]}
) 这是一个 set
。与 dict
不同,set
没有与其元素关联的键。所以你的数据结构看起来像 List[Set[List[Dict[str, str]]]]
.
第二:当我尝试 运行
# python 3.8.8
player_info = [{[{'tag': 'tag 1'}]},
{[{'tag': 'tag 2'}]}]
我收到错误 TypeError: unhashable type: 'list'
。那是因为您的代码试图在集合中包含一个列表。 python 中的集合成员资格要求成员可散列。但是,您不会找到在 list
对象上定义的 __hash__()
函数。即使您通过将 list
替换为 tuple
来解决此问题,您也会发现 dict
对象也不可散列。潜在的解决方案包括使用不可变对象,如 frozendict
或 tuple
,但那是另一个 post.
为了回答您的问题,我已将您的问题重新表述为
player_info = [[[{'tag': 'tag 1'}]],
[[{'tag': 'tag 2'}]]]
并将性能差异与 A) 显式循环进行比较:
for i in range(len(player_info)):
print(player_info[i][0][0]['tag'])
针对 B) 列表理解
[
print(single_player_info[0][0]['tag'])
for single_player_info in player_info
]
运行 jupyter 中的上述代码块与 %%timeit
细胞魔法,我得到:
A) 154 µs ± 14.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
和
B) 120 µs ± 11 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
注意:至少有两个原因导致该实验严重偏斜:
- 我仅使用您提供的数据 (N=2) 测试了这两个试验。我们很可能会观察到与初始条件所建议的不同的缩放行为。
print
消耗大量时间,使这个问题严重受制于内核状态
我希望这能回答你的问题。