为什么我们在 Python 字典生成器中有这种行为?
Why do we have this behavior in a Python dictionary generator?
为什么在第一种情况下字典键被覆盖,而在第二种情况下值被覆盖?
>>> a = {'a': 1, 'b': {'c': 3}}
>>> {None if v.__class__ == dict else k: v for k, v in a.items()}
{'a': 1, None: {'c': 3}}
>>> {k: v if v.__class__ != dict else None for k, v in a.items()}
{'a': 1, 'b': None}
你只是根据条件选择键,无论执行if还是执行else,值都是一样的。括号会使它更具可读性。
{(None if v.__class__ == dict else k): v for k, v in a.items()}
如果我们重写为标准循环,情况可能会变得更清楚(请注意,我使用 isinstance
作为更好的 class 检查):
选项 1:
d = {}
for k, v in a.items():
d[None if isinstance(v, dict) else k] = v
选项 2:
d = {}
for k, v in a.items():
d[k] = None if isinstance(v, dict) else v
很明显前者是修改key,后者是修改value。
你没有说出你实际上想要发生的事情,但如果你试图跳过 k: v
值是字典的对,即:
d = {}
for k, v in a.items():
if not isinstance(v, dict):
d[k] = v
那么 "dictionary comprehension" 等价物看起来像:
{k: v for k, v in a.items() if not isinstance(v, dict)}
请注意 if
条件出现在 之后 for
作为过滤器。
因为 if...else 比 : 绑定得更紧密。它确实很好,否则你会得到 {('a': 1), None},这不是命令。 :-)
你可能想要
{k: v for k, v in a.items() if not isinstance(v, dict)}
但要小心:您真的在这里只挑出听写吗?或者任何映射?或者任何不是 int 的东西?或者...
请参阅 dict comprehensions 上的语言规范:
如果你分析 dict-comprehension None if v.__class__ == dict else k: v for k, v in a.items()
,它必须匹配 expression : expression comp_for
的形式。那么让我们看看 comp_for
可能是什么。它指出 comp_for
必须以 for
开头并且其中只有一个 for 所以 for k, v in a.items()
是 for_comp
其余的需要以 expression : expression
,但只有一个冒号,所以第一个表达式(即键)将是 None if v.__class__ == dict else k
,第二个(即值)将是 v
。 if
和 else
是条件表达式的一部分。
理解的意思是对于a.items
中的每个k, v
与键None
组成一个键值对if v.__class__
== dict and k
否则值为 v
.
为什么在第一种情况下字典键被覆盖,而在第二种情况下值被覆盖?
>>> a = {'a': 1, 'b': {'c': 3}}
>>> {None if v.__class__ == dict else k: v for k, v in a.items()}
{'a': 1, None: {'c': 3}}
>>> {k: v if v.__class__ != dict else None for k, v in a.items()}
{'a': 1, 'b': None}
你只是根据条件选择键,无论执行if还是执行else,值都是一样的。括号会使它更具可读性。
{(None if v.__class__ == dict else k): v for k, v in a.items()}
如果我们重写为标准循环,情况可能会变得更清楚(请注意,我使用 isinstance
作为更好的 class 检查):
选项 1:
d = {}
for k, v in a.items():
d[None if isinstance(v, dict) else k] = v
选项 2:
d = {}
for k, v in a.items():
d[k] = None if isinstance(v, dict) else v
很明显前者是修改key,后者是修改value。
你没有说出你实际上想要发生的事情,但如果你试图跳过 k: v
值是字典的对,即:
d = {}
for k, v in a.items():
if not isinstance(v, dict):
d[k] = v
那么 "dictionary comprehension" 等价物看起来像:
{k: v for k, v in a.items() if not isinstance(v, dict)}
请注意 if
条件出现在 之后 for
作为过滤器。
因为 if...else 比 : 绑定得更紧密。它确实很好,否则你会得到 {('a': 1), None},这不是命令。 :-)
你可能想要
{k: v for k, v in a.items() if not isinstance(v, dict)}
但要小心:您真的在这里只挑出听写吗?或者任何映射?或者任何不是 int 的东西?或者...
请参阅 dict comprehensions 上的语言规范:
如果你分析 dict-comprehension None if v.__class__ == dict else k: v for k, v in a.items()
,它必须匹配 expression : expression comp_for
的形式。那么让我们看看 comp_for
可能是什么。它指出 comp_for
必须以 for
开头并且其中只有一个 for 所以 for k, v in a.items()
是 for_comp
其余的需要以 expression : expression
,但只有一个冒号,所以第一个表达式(即键)将是 None if v.__class__ == dict else k
,第二个(即值)将是 v
。 if
和 else
是条件表达式的一部分。
理解的意思是对于a.items
中的每个k, v
与键None
组成一个键值对if v.__class__
== dict and k
否则值为 v
.