使用或不使用dict.keys()访问Python字典键

5
通常我使用 keys() 方法访问字典键:
d = {'a':1, 'b':2, 'c':3}

for k in d.keys(): print k

但有时我会看到这段代码:
for k in d: print k

这段代码正确吗?安全吗?


有关时间的信息请参见此处:http://stackoverflow.com/a/14703683/1561176,以及有关从字典中获取信息的不同方法的一些信息。 - Inbar Rose
4个回答

11

回答你明确的问题,是的,它是安全的。

回答你不知道有的问题:

在Python 2.x中:dict.keys()返回键列表。

但是使用for k in dict遍历它们。

遍历比构造列表更快。

在Python 3+中,显式调用dict.keys()并不慢,因为它也返回一个迭代器。

大多数字典需求通常可以通过以下方式遍历items()而不是按键来解决:

for k, v in dict.items():
    # k is the key
    # v is the value
    print '%s: %s' % (k, v)

2
dict.keys()在Python2.x中返回一个list,但在3.x中不是这样,因此如果您在使用for k in d迭代字典时更改了该字典,则可能会存在差异,但是(至少在Python2.x上),遍历d.keys()时进行某些操作(例如插入新元素)的字典的最终行为是确定性的。 - mgilson

5

虽然已经提到过这一点,但我想加入一些确切的数字来讨论。因此,我进行了比较:

def iter_dtest(dtest):
    for i in dtest:
        pass

并且

def list_dtest(dtest):
    for i in dtest.keys():
        pass

使用了一个包含 1,000,000 个条目(浮点数键)的字典,并使用了 timeit 进行了 100 次重复测试。以下是测试结果:

Python 2.7.1:
iter_dtest: 3.92487884435s
list_dtest: 6.24848171448s

Python 3.2.1:
iter_dtest: 3.4850587113842555s
list_dtest: 3.535072302413432s

很明显,在Python 2.x中调用dtest.keys()存在一些缺陷。

1
你的比较有问题,因为在Python 2中,语义完全不同:dict.keys()必须分配并填充一个列表,而迭代(或使用dict.iterkeys()或dict.viewkeys())则不需要。在Python 3中,dict.keys()是一个视图(~dict.viewkeys()),因此基本上是免费的。 - Masklinn

3
第二个代码示例的行为等同于调用.keys(),因此是正确且安全的。

2
更准确地说,字典的__iter __()方法返回其键的迭代器,并且in d构造了这样一个迭代器。 - Tim Pietzcker
它是否明确调用了.keys(),还是只是使用了dict可迭代其键的属性...即for i in some_iterablefor i in some_list之间的区别... - Jon Clements
在某些细节上(至少在python2.x上),它们可能实际上不会产生相同的结果。请参阅我对InbarRose的帖子的评论。 - mgilson

0

这不是一样的。

for k in d: print k

不会创建额外的列表,而是

for k in d.keys(): print k

创建另一个列表,然后对其进行迭代。

至少在Python 2中是这样的。在Python 3中,dict.keys()是一个迭代器。

因此,您可以使用for k in d.iterkeys()for k in d。两者都会得到相同的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接