使用'for'循环迭代字典

Top*_*hef 2901 python dictionary python-2.7

我对以下代码感到有点困惑:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]
Run Code Online (Sandbox Code Playgroud)

我不明白的是这个key部分.Python如何识别它只需要从字典中读取密钥?keyPython中是一个特殊的词吗?或者它只是一个变量?

sbe*_*rry 5083

key 只是一个变量名.

for key in d:
Run Code Online (Sandbox Code Playgroud)

将简单地循环遍历字典中的键,而不是键和值.要循环键和值,您可以使用以下内容:

对于Python 2.x:

for key, value in d.iteritems():
Run Code Online (Sandbox Code Playgroud)

对于Python 3.x:

for key, value in d.items():
Run Code Online (Sandbox Code Playgroud)

要自己测试,请将单词更改keypoop.

对于Python 3.x,iteritems()已被简单替换items(),它返回由dict支持的类似集合的视图,iteritems()但更好.这也可以在2.7中获得viewitems().

该操作items()适用于2和3,但在2中它将返回字典(key, value)对的列表,这不会反映items()调用后发生的字典的更改.如果你想要3.x中的2.x行为,你可以打电话list(d.items()).

  • 添加一个忽略的原因,不要像这样访问值:在for循环中的d [key]导致密钥再次被哈希(获取值).当字典很大时,这个额外的哈希将增加总时间.这在Raymond Hettinger的技术讲座中进行了讨论https://www.youtube.com/watch?v=anrOzOapJ2E (130认同)
  • 可能有意义提到项目将以不可预测的顺序迭代,并且需要`sorted`来稳定它. (22认同)
  • @yugr 从Python 3.7开始,字典是按插入顺序排列的,这是一种语言功能。请参阅/sf/answers/2798652111/ (21认同)
  • @HarisankarKrishnaSwamy的替代方法是什么? (2认同)
  • @yugr为什么这么说?文档说`键和值按插入顺序进行迭代。`[https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects] (2认同)
  • @GezaTuri仅从Python 3.6开始(并且有传言称此“功能”可能在将来的版本中再次删除)。 (2认同)

ars*_*ars 407

并不是密钥是一个特殊的单词,而是字典实现了迭代器协议.您可以在您的类中执行此操作,例如,请参阅此问题以了解如何构建类迭代器.

在字典的情况下,它是在C级实现的.详情见PEP 234.特别是标题为"Dictionary Iterators"的部分:

  • 字典实现了一个tp_iter槽,它返回一个迭代字典键的高效迭代器.[...]这意味着我们可以写作

    for k in dict: ...
    
    Run Code Online (Sandbox Code Playgroud)

    这相当于,但比快得多

    for k in dict.keys(): ...
    
    Run Code Online (Sandbox Code Playgroud)

    只要不违反对字典的修改(通过循环或其他线程)的限制.

  • 向显示返回不同类型迭代器的字典添加方法:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    
    Run Code Online (Sandbox Code Playgroud)

    这意味着这for x in dict是简写for x in dict.iterkeys().

在Python 3 dict.iterkeys(),dict.itervalues()并且dict.iteritems()不再受支持.使用dict.keys(),dict.values()dict.items()代替.

  • 在python3 dict.iterkeys()中,不再支持dict.itervalues()和dict.iteritems().请改用dict.keys(),dict.values()和dict.items(). (69认同)

Joh*_*ooy 194

迭代dict迭代通过其键没有特定的顺序,你可以在这里看到:

编辑:( Python3.6中不再是这种情况,但请注意,它还不能保证行为)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']
Run Code Online (Sandbox Code Playgroud)

对于您的示例,最好使用dict.items():

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]
Run Code Online (Sandbox Code Playgroud)

这为您提供了元组列表.当你像这样循环它们时,每个元组都被解压缩kv自动:

for k,v in d.items():
    print(k, 'corresponds to', v)
Run Code Online (Sandbox Code Playgroud)

如果循环的主体只有几行,则在循环a时使用kv作为变量名dict是很常见的.对于更复杂的循环,使用更具描述性的名称可能是个好主意:

for letter, number in d.items():
    print(letter, 'corresponds to', number)
Run Code Online (Sandbox Code Playgroud)

养成使用格式字符串的习惯是个好主意:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))
Run Code Online (Sandbox Code Playgroud)

  • 从Python 3.7发行说明:"dict对象的插入顺序保存性质现在是Python语言规范的官方部分." (5认同)

sso*_*ler 76

key 只是一个变量.

对于Python2.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]
Run Code Online (Sandbox Code Playgroud)

... 或更好,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value
Run Code Online (Sandbox Code Playgroud)

对于Python3.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)
Run Code Online (Sandbox Code Playgroud)


Ale*_*ler 53

当您使用for .. in ..-syntax 迭代字典时,它总是遍历键(可以使用值访问dictionary[key]).

要迭代键值对,请使用for k,v in s.iteritems().

  • 请注意,对于Python 3,它是`items()`而不是`iteritems()` (33认同)

小智 36

对于遍历字典,可以使用以下代码。

dictionary= {1: "a", 2: "b", 3: "c"}

#To iterate over the keys
for key in dictionary.keys():
    print(key)

#To Iterate over the values
for value in dictionary.values():
    print(value)

#To Iterate both the keys and values
for key, value in dictionary.items():
    print(key, '\t', value)
Run Code Online (Sandbox Code Playgroud)


chr*_*yss 28

这是一个非常常见的循环习语.in是一个运营商.什么时候使用for key in dict,何时必须for key in dict.keys()David Goodger的Idiomatic Python文章.


jdh*_*hao 14

我有一个用例,我必须遍历dict以获取键,值对,以及指示我在哪里的索引.我是这样做的:

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)
Run Code Online (Sandbox Code Playgroud)

请注意,键周围的括号值很重要,如果没有括号,则会得到ValueError"没有足够的值来解包".

  • 这与问题有什么关系? (2认同)

Aar*_*all 12

使用'for'循环迭代字典

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...
Run Code Online (Sandbox Code Playgroud)

Python如何识别它只需要从字典中读取密钥?关键是Python中的一个特殊词吗?或者它只是一个变量?

这不仅仅是for循环.这里重要的一词是"迭代".

字典是键到值的映射:

d = {'x': 1, 'y': 2, 'z': 3} 
Run Code Online (Sandbox Code Playgroud)

每当我们迭代它时,我们迭代键.变量名key只是为了描述 - 而且它非常适合于此目的.

这发生在列表理解中:

>>> [k for k in d]
['x', 'y', 'z']
Run Code Online (Sandbox Code Playgroud)

它发生在我们将字典传递给列表(或任何其他集合类型对象)时:

>>> list(d)
['x', 'y', 'z']
Run Code Online (Sandbox Code Playgroud)

Python迭代的方式是,在需要的上下文中,它调用__iter__对象的方法(在本例中是字典),它返回一个迭代器(在本例中是一个keyiterator对象):

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>
Run Code Online (Sandbox Code Playgroud)

我们不应该自己使用这些特殊方法,而是使用相应的内置函数来调用它,iter:

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>
Run Code Online (Sandbox Code Playgroud)

迭代器有一个__next__方法 - 但我们用内置函数调用它next:

>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
Run Code Online (Sandbox Code Playgroud)

当迭代器耗尽时,它会升起StopIteration.这就是Python知道退出for循环,列表理解,生成器表达式或任何其他迭代上下文的方式.一旦迭代器引发StopIteration它将始终引发它 - 如果你想再次迭代,你需要一个新的.

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']
Run Code Online (Sandbox Code Playgroud)

回到dicts

我们已经看到dicts在许多情况下迭代.我们所看到的是,无论何时我们迭代dict,我们都会得到密钥.回到原始示例:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
Run Code Online (Sandbox Code Playgroud)

如果我们更改变量名称,我们仍然会获得密钥.我们来试试吧:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3
Run Code Online (Sandbox Code Playgroud)

如果我们想迭代值,我们需要使用.valuesdicts 的方法,或者两者一起使用.items:

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]
Run Code Online (Sandbox Code Playgroud)

在给出的示例中,迭代这样的项目会更有效:

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)
Run Code Online (Sandbox Code Playgroud)

但是出于学术目的,这个问题的例子很好.


Ama*_*mar 8

这将按升序按排序打印输出。

d = {'x': 3, 'y': 1, 'z': 2}

def by_value(item):
    return item[1]

for key, value in sorted(d.items(), key=by_value):
    print(key, '->', value)
Run Code Online (Sandbox Code Playgroud)

输出:

y -> 1
z -> 2
x -> 3
Run Code Online (Sandbox Code Playgroud)


Nei*_*o_O 7

要迭代键,使用my_dict.keys(). 如果你试图做这样的事情:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1
Run Code Online (Sandbox Code Playgroud)

它会产生运行时错误,因为您在程序运行时更改了密钥。如果您绝对想减少时间,请使用这种for key in my_dict方式,但您已被警告。


Ank*_*wal 7

您可以dicttype在GitHub上检查CPython的实现.这是实现dict迭代器的方法的签名:

_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
             PyObject **pvalue, Py_hash_t *phash)
Run Code Online (Sandbox Code Playgroud)

CPython dictobject.c


Pet*_*leg 5

如果您正在寻找一个清晰直观的示例:

cat  = {'name': 'Snowy', 'color': 'White' ,'age': 14}
for key , value in cat.items():
   print(key, ': ', value)
Run Code Online (Sandbox Code Playgroud)

结果:

cat  = {'name': 'Snowy', 'color': 'White' ,'age': 14}
for key , value in cat.items():
   print(key, ': ', value)
Run Code Online (Sandbox Code Playgroud)