在 Python 中对字典使用列表理解
Using List Comprehension with Dictionaries in Python
我正在努力了解列表推导式,我可以理解它们的基本工作原理,但我觉得我应该能够用我的代码做一些我似乎做不到的事情开始工作。
给定一个字典:
{2: {11}, 9: {11, 8, 10}, 10: {11, 3}, 11: {7, 5}, 8: {7, 3}}
有几个片段我觉得如果我知道的话应该可以减少到更少的行数:
for k, v in d.items():
dag[k] = v
for val in v:
if val not in d.keys():
dag[val] = None
和:
t = []
for k, v in d.items():
if not v:
t.append(k)
d.pop(k)
我的尝试在以下方面有所变化:
for [k, v in d.items() if not v]:
但这一直告诉我它需要一个 else 语句,none 我读过的内容帮助回答了 how/if 这是可能的。
如果您想保留具有错误值的键,语法为:
[ k for k, v in d.items() if not v]
这相当于你最后一个循环栏 d.pop(k)
我不确定你是否想要。第一个 k
是我们附加到列表的内容,for k, v
是 d.items 中的每个键和值,而 if not v
意味着我们只保留具有错误值的 k。
如果你真的想要一个没有这些键和值的字典,你可以使用一个字典理解,其中的逻辑完全相同,除了我们正在创建 key/value 配对而不是只保留列表理解中的键:
{ k:v for k, v in d.items() if not v}
至于你的第一个代码,我不确定你想要它做什么,但你不应该调用 .keys
,在 python2 中创建一个列表并进行查找 O(n)
与 0(1)
相反,在 python 3 中,这是一个不必要的函数调用。
在您的第一个片段中,您基本上将所有节点默认为 dag
中的 None
。您可以颠倒这些步骤并避免测试已经存在的密钥:
dag = dict.fromkeys(node for v in d.values() for node in v)
dag.update(d)
这将创建一个字典,其中包含给定键的所有 None
值(来自生成器表达式),然后更新以插入所有已知边。
在您的代码中,您使用了 if val not in d.keys()
;这在功能上等同于 if val not in d
,但没有对 d.keys()
的冗余调用,它创建了一个新对象(在 Python 2 中,一个包含所有键的列表,使搜索 extra 效率低下,在 Python 3 中创建了一个字典视图)。始终使用较短的形式。
请注意,您在 d
中用作值的 set
对象现在与 dag
共享;您对这些集合所做的任何更改都将反映在两个词典中。
创建一个没有值的节点序列将是:
nodes_without_exits = [node for node, edges in d.items() if not node]
列表理解仍然需要生产者表达式,产生要插入到列表中的值的部分;这里是 node
,列表是用字典的键构建的。
我正在努力了解列表推导式,我可以理解它们的基本工作原理,但我觉得我应该能够用我的代码做一些我似乎做不到的事情开始工作。
给定一个字典:
{2: {11}, 9: {11, 8, 10}, 10: {11, 3}, 11: {7, 5}, 8: {7, 3}}
有几个片段我觉得如果我知道的话应该可以减少到更少的行数:
for k, v in d.items():
dag[k] = v
for val in v:
if val not in d.keys():
dag[val] = None
和:
t = []
for k, v in d.items():
if not v:
t.append(k)
d.pop(k)
我的尝试在以下方面有所变化:
for [k, v in d.items() if not v]:
但这一直告诉我它需要一个 else 语句,none 我读过的内容帮助回答了 how/if 这是可能的。
如果您想保留具有错误值的键,语法为:
[ k for k, v in d.items() if not v]
这相当于你最后一个循环栏 d.pop(k)
我不确定你是否想要。第一个 k
是我们附加到列表的内容,for k, v
是 d.items 中的每个键和值,而 if not v
意味着我们只保留具有错误值的 k。
如果你真的想要一个没有这些键和值的字典,你可以使用一个字典理解,其中的逻辑完全相同,除了我们正在创建 key/value 配对而不是只保留列表理解中的键:
{ k:v for k, v in d.items() if not v}
至于你的第一个代码,我不确定你想要它做什么,但你不应该调用 .keys
,在 python2 中创建一个列表并进行查找 O(n)
与 0(1)
相反,在 python 3 中,这是一个不必要的函数调用。
在您的第一个片段中,您基本上将所有节点默认为 dag
中的 None
。您可以颠倒这些步骤并避免测试已经存在的密钥:
dag = dict.fromkeys(node for v in d.values() for node in v)
dag.update(d)
这将创建一个字典,其中包含给定键的所有 None
值(来自生成器表达式),然后更新以插入所有已知边。
在您的代码中,您使用了 if val not in d.keys()
;这在功能上等同于 if val not in d
,但没有对 d.keys()
的冗余调用,它创建了一个新对象(在 Python 2 中,一个包含所有键的列表,使搜索 extra 效率低下,在 Python 3 中创建了一个字典视图)。始终使用较短的形式。
请注意,您在 d
中用作值的 set
对象现在与 dag
共享;您对这些集合所做的任何更改都将反映在两个词典中。
创建一个没有值的节点序列将是:
nodes_without_exits = [node for node, edges in d.items() if not node]
列表理解仍然需要生产者表达式,产生要插入到列表中的值的部分;这里是 node
,列表是用字典的键构建的。