dict.iterkeys() 是 Python 2 中的一个方法,用于返回一个字典键的迭代器,在 Python 3 中,这个方法已经被移除了,在 Python 3 中,直接使用 dict.keys() 就会返回一个类似迭代器的视图对象,这通常是更推荐的方式。

Python 2 中的 iterkeys()
在 Python 2 中,字典有三种与键相关的方法:
keys(): 返回一个列表,包含字典中所有的键。iterkeys(): 返回一个迭代器,用于遍历字典中所有的键。viewkeys(): 返回一个视图对象(Python 2.7+ 引入),这是字典键的动态视图。
为什么要有 iterkeys()?
主要出于性能和内存的考虑,当字典非常大时,keys() 会一次性将所有键加载到内存中生成一个列表,这可能消耗大量内存,而 iterkeys() 返回一个迭代器,它是一次性生成一个值,不会一次性占用大量内存,非常适合遍历大型字典。
Python 2 示例
# Python 2
d = {'a': 1, 'b': 2, 'c': 3}
# 1. keys() - 返回列表
print "Using keys():"
keys_list = d.keys()
print keys_list # 输出: ['a', 'b', 'c'] (顺序可能不同)
print type(keys_list) # 输出: <type 'list'>
print "\nUsing iterkeys():"
# 2. iterkeys() - 返回迭代器
keys_iterator = d.iterkeys()
print keys_iterator # 输出: <dictionary-keyiterator object at 0x...>
print type(keys_iterator) # 输出: <type 'dictionary-keyiterator'>
# 遍历迭代器
print "Iterating over the iterator:"
for key in keys_iterator:
print key
# 迭代器只能被遍历一次,再次遍历会得到空的结果
print "\nTrying to iterate again:"
for key in keys_iterator:
print key # 这行代码不会执行
Python 3 中的变化
在 Python 3 中,设计者对字典的这些方法进行了简化和统一:
dict.keys(): 不再返回一个列表,而是返回一个字典键的视图对象 (dict_keys),这个视图对象是动态的(会随着字典的改变而改变),并且是可迭代的,它也支持集合操作(如&, )。dict.iterkeys(): 被移除了,因为dict.keys()返回的视图对象已经是可迭代的,并且具有内存效率高的优点,所以不再需要单独的iterkeys()方法。dict.viewkeys(): 也被移除了,其功能由dict.keys()统一。
Python 3 示例
# Python 3
d = {'a': 1, 'b': 2, 'c': 3}
# 在 Python 3 中,keys() 返回的是一个视图对象
print "Using keys() in Python 3:"
keys_view = d.keys()
print keys_view # 输出: dict_keys(['a', 'b', 'c']) (顺序是插入顺序,Python 3.7+)
print type(keys_view) # 输出: <class 'dict_keys'>
# 这个视图对象是可迭代的,可以直接用于 for 循环
print "\nIterating over the view object:"
for key in keys_view:
print key
# 视图对象是动态的
print "\nOriginal view:", keys_view
d['d'] = 4
print "Dictionary after adding a key:", d
print "View after dictionary change:", keys_view # 视图也自动更新了
# 你可以像迭代器一样使用它,但它本身不是迭代器
# 它可以被多次遍历
print "\nIterating over the view object again:"
for key in keys_view:
print key
如何在 Python 3 中模拟 iterkeys() 的行为?
虽然 iterkeys() 被移除了,但如果你确实需要一个“纯”的迭代器(你需要一个只能遍历一次的对象,并且不关心视图的动态性),你可以这样做:

最简单的方式就是将 d.keys() 传递给内置的 iter() 函数。
# Python 3
d = {'a': 1, 'b': 2, 'c': 3}
# 获取一个真正的迭代器
keys_iterator = iter(d.keys())
print(keys_iterator) # 输出: <dict_keyiterator object at 0x...>
print(type(keys_iterator)) # 输出: <class 'dict_keyiterator'>
# 遍历它
for key in keys_iterator:
print(key)
# 再次遍历会得到空结果
print("\nTrying to iterate again:")
for key in keys_iterator:
print(key) # 不会执行
iter() 函数做了什么?
当你对一个可迭代对象(如 dict_keys 视图、列表、元组等)调用 iter() 时,它会返回该对象的迭代器,对于字典的 keys() 视图,iter() 返回的正是和 Python 2 中 iterkeys() 类似的 dict_keyiterator 对象。
总结与对比
| 特性 | Python 2 iterkeys() |
Python 3 keys() |
Python 3 iter(d.keys()) |
|---|---|---|---|
| 返回类型 | 迭代器 (dictionary-keyiterator) |
视图对象 (dict_keys) |
迭代器 (dict_keyiterator) |
| 内存效率 | 高,惰性计算 | 高,惰性计算 | 高,惰性计算 |
| 可遍历次数 | 仅一次 | 无限次 | 仅一次 |
| 动态性 | 否(基于字典快照) | 是(随字典改变) | 否(基于视图快照) |
| Python 3 推荐度 | N/A (已移除) | ⭐⭐⭐⭐⭐ (首选) | ⭐⭐ (特殊需求时使用) |
最佳实践建议
-
如果你在使用 Python 3:
- 始终使用
my_dict.keys(),它提供了视图对象的所有优点:动态、可迭代、支持集合操作,并且内存效率高,这是最现代、最 Pythonic 的方式。 - 只有在你明确需要一个只能消耗一次的迭代器时(某些特定的算法库要求),才考虑使用
iter(my_dict.keys())。
- 始终使用
-
如果你在编写需要同时兼容 Python 2 和 Python 3 的代码:
(图片来源网络,侵删)- 你可以使用
six库,它提供了跨版本的兼容性。 - 或者,你可以使用一个简单的
try...except块来模拟。
使用
six库的例子:# pip install six from six import iterkeys d = {'a': 1, 'b': 2} for key in iterkeys(d): print(key)six.iterkeys()会根据 Python 版本自动选择正确的方法。手动兼容的例子:
try: # Python 2 iterkeys_method = dict.iterkeys except AttributeError: # Python 3 iterkeys_method = lambda d: iter(d.keys()) d = {'a': 1, 'b': 2} for key in iterkeys_method(d): print(key) - 你可以使用
