杰瑞科技汇

python 字典 iterkeys

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

python 字典 iterkeys-图1
(图片来源网络,侵删)

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() 被移除了,但如果你确实需要一个“纯”的迭代器(你需要一个只能遍历一次的对象,并且不关心视图的动态性),你可以这样做:

python 字典 iterkeys-图2
(图片来源网络,侵删)

最简单的方式就是将 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 (已移除) ⭐⭐⭐⭐⭐ (首选) ⭐⭐ (特殊需求时使用)

最佳实践建议

  1. 如果你在使用 Python 3

    • 始终使用 my_dict.keys(),它提供了视图对象的所有优点:动态、可迭代、支持集合操作,并且内存效率高,这是最现代、最 Pythonic 的方式。
    • 只有在你明确需要一个只能消耗一次的迭代器时(某些特定的算法库要求),才考虑使用 iter(my_dict.keys())
  2. 如果你在编写需要同时兼容 Python 2 和 Python 3 的代码

    python 字典 iterkeys-图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)
分享:
扫描分享到社交APP
上一篇
下一篇