Python 为什么要使用dict.keys?

Python 为什么要使用dict.keys?,python,dictionary,Python,Dictionary,我最近写了一些类似这样的代码: # dct is a dictionary if "key" in dct.keys(): 然而,我后来发现,我可以通过以下方法获得相同的结果: if "key" in dct: 这一发现让我思考,我开始运行一些测试,看看是否会出现这样的情况:我必须使用字典的键方法。然而,我的结论是没有,没有 如果我想要列表中的键,我可以执行以下操作: keys_list = list(dct) for key in dct: ... 如果我想迭代这些键,我可以执

我最近写了一些类似这样的代码:

# dct is a dictionary
if "key" in dct.keys():
然而,我后来发现,我可以通过以下方法获得相同的结果:

if "key" in dct:
这一发现让我思考,我开始运行一些测试,看看是否会出现这样的情况:我必须使用字典的
方法。然而,我的结论是没有,没有

如果我想要列表中的键,我可以执行以下操作:

keys_list = list(dct)
for key in dct:
    ...
如果我想迭代这些键,我可以执行以下操作:

keys_list = list(dct)
for key in dct:
    ...
最后,如果我想测试一个键是否在
dct
中,我可以像上面那样在
中使用


总而言之,我的问题是:我是否遗漏了什么?有没有可能出现这样一种情况,我必须使用
keys
方法?…或者它仅仅是早期安装的Python遗留下来的方法,应该被忽略?

假设您没有使用Python 3,
list(dct)
相当于
dct.keys()
。你用哪一种取决于个人喜好。我个人认为,
dct.keys()
稍微清晰一些,但对每个人来说都是自己的

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


在Python3中,
dct.keys()
返回一个“dictionary view对象”,因此如果需要在循环上下文的
之外获得键的非物质化视图(这对于大型字典可能很有用),则需要在Python3上使用
dct.keys()
,使用
dct.keys()
来获得,它允许您仅对关键点执行设置操作:

>>> for sharedkey in dct1.keys() & dct2.keys():  # intersection of two dictionaries
...     print(dct1[sharedkey], dct2[sharedkey])
在Python2.7中,您将使用
dct.viewkeys()
实现这一点

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

您确实不希望这些用于迭代或成员资格测试;始终分别对dct中的键使用
和dct中的键使用

来源:

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

当迭代器出现时,dicts就变得易于使用了,因为它更方便、更快,而且说起来更全面

for key in d:

这样做的副作用是使
d.keys()
完全多余<代码>列表(d)
iter(d)
现在做了
d的所有事情。keys()
以更干净、更通用的方式做了。然而,他们无法摆脱
,因为已经有太多的代码调用了它

(此时,dicts还得到了一个
\uuuu contains
方法,因此您可以说
在d中键入
而不是
d.has_key(key)
。这与
在d中键入
时的对称性很短,很好地对称;对称性也是为什么在dict上迭代会给出键而不是(key,value)对。)

在Python3中,受Java集合框架的启发,dicts的
、和
方法都发生了更改。它们不会返回列表,而是返回原始dict的视图。键视图和项视图将支持类似集合的操作,并且所有视图都是围绕基础dict的包装,反映对dict的任何更改。这使得
键再次有用。

键入dict 比检查快得多
输入dict.keys()

我同意汤姆的看法。keys()是更为传统和惯用的python(例如,它是
pythonic
)。像
list(dct)
这样的晦涩语法技巧与其说是惯用用法,不如说是一种噱头——很多时候,noobpython用户需要更深入地了解
list(dct)
是否返回键列表或项列表。对于任何阅读您的代码的人来说,dct.keys()在初始检查时都是明确无误的,甚至对于python noob也是如此很好,因为它是python的惯用用法。从技术上讲,
dct.keys()
是python 3中的“字典视图对象”,而不是迭代器:
type(dct.keys())
,而
type(iter(dct))
。(参见Martijn和user2357112的答案)因此
next(iter(dct))
是可以的,但是
next(dct.keys())
不是。啊,你当然是对的,@torek。我会更新我的答案。谢谢。@karthikr:在这两种情况下,
for
都创建了一个迭代器对象(iter()
函数的返回值,该函数按顺序生成值。这两种情况都返回字典键,区别在于使用
dict.keys()
需要首先进行属性查找和函数调用。因此,效率较低。@karthikr:在Python 2中添加此功能。
.keys()
首先创建一个包含字典所有键的新列表。此外,d中的
k(其中d是字典)可能比l中的
k(其中l是列表)快得多后者对列表进行线性搜索,而前者在字典中进行哈希查找。哈希查找为O(1),而列表搜索为O(len(l))。