Python中用于字典的enumerate()函数

166

我知道我们使用 enumerate 来遍历一个列表,但是我尝试使用它来遍历一个字典,却没有报错。

代码:

enumm = {0: 1, 1: 2, 2: 3, 4: 4, 5: 5, 6: 6, 7: 7}

for i, key in enumerate(enumm):
    print(i, key)

输出:

0 0

1 1

2 2

3 4

4 5

5 6

6 7

请问有人可以解释一下输出结果吗?


5
for i, j in enumerate(enumm) 这段代码会使得 i 在每次迭代时自增,而 j 则会获取 enumerate 函数参数中的常规元素,这里是一个字典。遍历字典本质上就是遍历它的键。 - Divyanshu Srivastava
11个回答

267

除了已经提供的答案之外,Python中还有一种非常好的模式,可以让您枚举字典的键和值。

通常情况下,您会枚举字典的键:

example_dict = {1:'a', 2:'b', 3:'c', 4:'d'}

for i, k in enumerate(example_dict):
    print(i, k)

输出结果为:

0 1
1 2
2 3
3 4

但如果你想要枚举键和值,这是方法:

for i, (k, v) in enumerate(example_dict.items()):
    print(i, k, v)

输出结果为:

0 1 a
1 2 b
2 3 c
3 4 d

9
你也可以简单地使用 dictionary.items()(不需要 enumerate)来获取一个键值对的视图对象,它是一个元组列表。 - Tiago Martins Peres
2
我不确定为什么这是最高评价的答案。它基本上是太多代码,而且可能会得到错误的答案。在使用带有字典的enumerate时存在潜在危险。Python在使用enumerate时不保证键的顺序; 可能会在后续运行中以不同的顺序发出键。@roadrunner66的回答是最正确的解决方案。 - Jim
3
这对于Python 3.7+来说是可以的,因为字典被保证是有序的。 - Tom2shoes

78

输出的第一列是enumm中每个项目的索引,第二列是对应的键。如果要迭代字典,请使用.items():

for k, v in enumm.items():
    print(k, v)

输出应该看起来像这样:

0 1
1 2
2 3
4 4 
5 5
6 6
7 7

72

我只是想补充一下,如果你想枚举一个字典的索引、键和值,你的for循环应该像这样:

for index, (key, value) in enumerate(your_dict.items()):
    print(index, key, value)

7
这个问题涉及语法问题,而这个答案提供了在enumerate(d.items())中添加两个括号的最短解决方案: idx, (k, v) in enumerate(d.items()): - Sean Pianka
2
嗨,肖恩,我不确定你是否同意这个答案,还是只是说较短的变量名能够产生更好的答案? - Jordan Mackie

44
dict1={'a':1, 'b':'banana'}

在Python 2.x中列出字典:

for k,v in dict1.iteritems():
        print k,v 

在 Python 3.x 中使用:
for k,v in dict1.items():
        print(k,v)
# a 1
# b banana

最后,正如其他人所指出的那样,如果您想要一个运行中的索引,您也可以拥有它:

for i  in enumerate(dict1.items()):
   print(i)  

 # (0, ('a', 1))
 # (1, ('b', 'banana'))

但这样做就违背了字典(映射,关联数组)的目的,它是一种高效的数据结构,用于电话簿式查找。字典排序可能是实现的附带效果,不应该依赖于它。如果您需要顺序,请使用 OrderedDict

2
它不允许我在此帖子中进行2个字符的编辑,但OP将其标记为Python 3,因此print语句需要在k、v周围加上括号。 - hostingutilities.com
@Mr. Me,谢谢,我会修复的。 - roadrunner66
19
需要注意的是,这仅适用于Python2。在Python3中已删除dict.iteritems(),请参见https://dev59.com/q10a5IYBdhLWcg3wW3nN。 - gyger
1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - lkahtz
更新了Python3和Python2的区别,并在enumerate上添加了注释。 - roadrunner66

6
由于您使用了enumerate,所以您的i实际上是键的索引而不是键本身。
因此,即使没有键3,在行3 4的第一列中仍会得到3enumerate遍历数据结构(无论是列表还是字典),同时提供当前迭代号码。
因此,这里的列是字典enum中的键之前的迭代号码。
其他解决方案已经展示了如何遍历键和值对,所以我不会在我的解决方案中重复。

6

enumerate()函数在处理列表时,实际上会返回列表中每个元素的索引和值。

例如:

l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i, j in enumerate(list):
    print(i, j)

提供

0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9

第一列表示项目的索引,第二列表示项目本身。

在字典中

enumm = {0: 1, 1: 2, 2: 3, 4: 4, 5: 5, 6: 6, 7: 7}
for i, j in enumerate(enumm):
    print(i, j)

它给出输出结果。

0 0
1 1
2 2
3 4
4 5
5 6
6 7

第一列给出了key:value的索引,第二列表示字典enummkeys

所以如果您希望第一列是values而第二列是keys,最好尝试使用dict.iteritems()(Python 2)dict.items()(Python 3)。

for i, j in enumm.items():
    print(i, j)

输出

0 1
1 2
2 3
4 4
5 5
6 6
7 7

Voila

1
这并不适用于字典。你的代码将使用索引(进行迭代),但不会给出字典的键值组合。请改用dict.items()。 - Matthias
是的,您也可以使用dict.items()。感谢您的纠正。 - Abhishek Roy

4
  1. 在Python中迭代一个字典意味着以与dict.keys()相同的方式迭代其键。
  2. 键的顺序由实现代码决定,您无法期望某些特定的顺序:

    键和值的迭代顺序是任意的,这是非随机的,因Python实现而异,并取决于字典插入和删除的历史记录。如果键、值和项视图在没有对字典进行干预的情况下进行迭代,则项目的顺序将直接对应。

这就是为什么您在第一列看到索引0到7。它们是由enumerate生成的,并始终按正确顺序排列。此外,您可以在第二列看到字典的键0到7。它们没有排序。


3

Python3:

一种解决方案:

enumm = {0: 1, 1: 2, 2: 3, 4: 4, 5: 5, 6: 6, 7: 7}
for i, k in enumerate(enumm):
    print("{}) d.key={}, d.value={}".format(i, k, enumm[k]))

Output:
0) enumm.key=0, enumm.value=1
1) enumm.key=1, enumm.value=2
2) enumm.key=2, enumm.value=3
3) enumm.key=4, enumm.value=4
4) enumm.key=5, enumm.value=5
5) enumm.key=6, enumm.value=6
6) enumm.key=7, enumm.value=7

另一个例子:
d = {1 : {'a': 1, 'b' : 2, 'c' : 3},
     2 : {'a': 10, 'b' : 20, 'c' : 30}
    }    
for i, k in enumerate(d):
        print("{}) key={}, value={}".format(i, k, d[k])

Output:    
    0) key=1, value={'a': 1, 'b': 2, 'c': 3}
    1) key=2, value={'a': 10, 'b': 20, 'c': 30}

3
这一定让人感到困惑。这就是其中的原因。enumerate的第一个值(在本例中为i)返回下一个索引值,从0开始,所以是0、1、2、3……无论字典中有什么,它总是返回这些数字。enumerate的第二个值(在本例中为j)返回您的字典/枚举中的值(在Python中我们将其称为字典)。你真正想做的是像roadrunner66回答的那样。

3

在键内包含索引可能会很有用:

d = {'a': 1, 'b': 2}
d = {(i, k): v for i, (k, v) in enumerate(d.items())}

输出:

{(0, 'a'): True, (1, 'b'): False}

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