35

我最近写了一些看起来像这样的代码:

# dct is a dictionary
if "key" in dct.keys():

但是,我后来发现我可以通过以下方式获得相同的结果:

if "key" in dct:

这个发现让我开始思考,我开始进行一些测试,看看是否存在必须使用keys字典方法的场景。然而,我的结论是不,没有。

如果我想要列表中的键,我可以这样做:

keys_list = list(dct)

如果我想遍历键,我可以这样做:

for key in dct:
    ...

最后,如果我想测试一个键是否在 中dct,我可以in像上面那样使用。

总结一下,我的问题是:我错过了什么吗?是否存在我必须使用该keys方法的情况?...或者它只是早期安装 Python 的遗留方法,应该被忽略?

4

4 回答 4

30

在 Python 3 上,用于dct.keys()获取字典视图对象,它允许您仅对键进行设置操作:

>>> for sharedkey in dct1.keys() & dct2.keys():  # intersection of two dictionaries
...     print(dct1[sharedkey], dct2[sharedkey])

在 Python 2.7 中,您会使用dct.viewkeys()它。

在 Python 2 中,dct.keys()返回一个列表,即字典中键的副本。这可以围绕一个单独的对象传递,该对象可以自行操作,包括在不影响字典本身的情况下删除元素;但是,您可以使用 来创建相同的列表list(dct),它适用于 Python 2 和 3。

您确实不希望将其中任何一个用于迭代或成员测试;总是分别使用for key in dctkey in dct

于 2013-07-13T21:15:04.010 回答
13

来源:PEP 234PEP 3106

dict.keys由于历史原因,Python 2 的相对无用的方法存在。最初,dicts 是不可迭代的。事实上,没有迭代器这样的东西。通过调用元素访问方法迭代序列__getitem__,增加整数索引,直到IndexError引发 an。要迭代 dict 的键,您必须调用该keys方法来获取显式的键列表并对其进行迭代。

当迭代器进入时,dicts 变成了可迭代的,因为它更方便、更快,而且说起来更好

for key in d:

for key in d.keys()

d.keys()这具有完全多余的副作用。list(d)现在以更清洁、更通用的方式完成了iter(d)所有操作。d.keys()但是,他们无法摆脱keys,因为已经有很多代码调用了它。

(此时,dicts 也有一个__contains__方法,所以你可以说,key in d而不是d.has_key(key)。这更短,并且与 很好对称for key in d;对称性也是为什么迭代 dict 给出键而不是 (key, value) 对的原因。)

在 Python 3 中,受 Java Collections Framework 的启发,dict 的keysvaluesitems方法发生了变化。他们不会返回列表,而是返回原始字典的视图。key 和 item 视图将支持类似集合的操作,并且所有视图都将是底层 dict 的包装器,反映对 dict 的任何更改。这keys再次变得有用。

于 2013-07-13T22:21:31.600 回答
2

假设您没有使用 Python 3,list(dct)则相当于dct.keys(). 您使用哪一个是个人喜好问题。我个人认为dct.keys()稍微清楚一点,但每个人都有自己的想法。

在任何情况下,都没有“需要”使用dct.keys()本身的场景。

在 Python 3 中,dct.keys()返回一个“字典视图对象”,因此如果您需要在循环上下文之外获取键的非物化视图(这可能对大型字典有用)for,您需要使用dct.keys().

于 2013-07-13T21:01:17.923 回答
0

dict 中的键比检查 dict.keys() 中的键快得多

于 2018-09-24T01:30:26.833 回答