Pythonでは辞書を巡回中に要素を変更すると異常な解決方法が発生します。


まず、Pythonで辞書を巡る基本的な方法を振り返ってみます。
スクリプト:

#!/usr/bin/python 
dict={"a":"apple","b":"banana","o":"orange"} 
 
print "##########dict######################" 
for i in dict: 
    print "dict[%s]=" % i,dict[i] 
 
print "###########items#####################" 
for (k,v) in dict.items(): 
    print "dict[%s]=" % k,v 
 
print "###########iteritems#################" 
for k,v in dict.iteritems(): 
    print "dict[%s]=" % k,v 
 
print "###########iterkeys,itervalues#######" 
for k,v in zip(dict.iterkeys(),dict.itervalues()): 
    print "dict[%s]=" % k,v
 
実行結果:

##########dict###################### 
dict[a]= apple 
dict[b]= banana 
dict[o]= orange 
###########items##################### 
dict[a]= apple 
dict[b]= banana 
dict[o]= orange 
###########iteritems################# 
dict[a]= apple 
dict[b]= banana 
dict[o]= orange 
###########iterkeys,itervalues####### 
dict[a]= apple 
dict[b]= banana 
dict[o]= orange
ええ、それから本題に入ります。
Python辞書に関する論争の一節です。
まず切り取ります

#       dict
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#     dict,       0  ,   
>>> for k in d:
...  if d[k] == 0:
...   del(d[k])
...
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
#       ,  0   ,      。
>>> d
{'a': 1, 'c': 1, 'd': 0}

>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#d.keys()         
>>> d.keys()
['a', 'c', 'b', 'd']
#    ,     ,            d.keys()  list  。
>>> for k in d.keys():
...  if d[k] == 0:
...   del(d[k])
...
>>> d
{'a': 1, 'c': 1}
#      
>>>

#       dict
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#     dict,       0  ,   
>>> for k in d:
...  if d[k] == 0:
...   del(d[k])
...
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
#       ,  0   ,      。
>>> d
{'a': 1, 'c': 1, 'd': 0}
 
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#d.keys()         
>>> d.keys()
['a', 'c', 'b', 'd']
#    ,     ,            d.keys()  list  。
>>> for k in d.keys():
...  if d[k] == 0:
...   del(d[k])
...
>>> d
{'a': 1, 'c': 1}
#      
>>>

実はこの問題はもともととても簡単です。つまり、辞書を遍歴すると、彼を変えました。例えば、ある要素を削除すると、遍歴して脱退し、dictory changed size during iterationの異常を投げ出します。
解决方法は辞书のキーを遍歴して、辞书のキーの値を基础にして遍歴して、このように変化しました。
しかし、次にはもう一人の大神が高説を投げかける。
まず、pythonはローズマリーを使うことを勧めています。つまりfor k in adict形式です。その次に、巡回中に容器の中の元素を削除して、C++STLとPythonなどの倉庫の中で、すべて推薦しないので、このような情況がよくあなたの設計案に問題があると説明しました。すべて特殊な要求があります。pythonの中で、adict.keyを使って拷問をします。最後に、すべてのPython容器はスレッドの安全を承諾しません。マルチスレッドを作るには、自身がロックをかけなければなりません。これは業務コードの設計に問題があると説明しました。
ただし、「遍歴中に特定の要素を削除する」という特例から、「手順を踏むときは、for k in d.keys()を使う習慣を身につける」ということになります。一般的なエルゴードでは、for k in adictを使用するべきです。
また、「遍歴中に要素を削除する」というニーズに対しては、pythonicのやり方はadict={k,v for adict.iteritems()if v!=0}またはalist=[i for i in alist if i!=0)
この書き方は私の目の前を明るくします。どうしてこの文法がありますか?
もう少しよく見ると、彼はこの意味かもしれません。

#!/usr/bin/env python
# -*- coding=utf-8 -*-
a = {'a':1, 'b':0, 'c':1, 'd':0}
b={}
for k,v in a.items():
  if v != 0:
    b.update({k:v})
adict = b
del b
print a

#!/usr/bin/env python
# -*- coding=utf-8 -*-
a = {'a':1, 'b':0, 'c':1, 'd':0}
b={}
for k,v in a.items():
  if v != 0:
    b.update({k:v})
adict = b
del b
print a

正しいかどうか分かりません。
この書き方からいきなり三元の操作子を思い出しました。よく見ると違います。以前はGoolgeから解決案がありました。

val = float(raw_input("Age: "))
status = ("working","retired")[val>65]
print "You should be",status

val = float(raw_input("Age: "))
status = ("working","retired")[val>65]
print "You should be",status

val>65は論理式で、0または1を返して、ちょうど前の元のグループのIDとして値を取るのは素晴らしいです。
Googleの資料の中にもう一つのバージョンがあります。

#V1 if X else V2
s = None
a = "not null" if s == None else s
print a
#'not null'

後に発表されたのは、ワバミユーザーグループ(中国語Python技術メールリスト)の中で言及された後、多くの大神が次のように答えました。

>>> alist = [1,2,0,3,0,4,5]
>>> alist = [i for i in alist if i != 0]
>>> alist

[1, 2, 3, 4, 5]

>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
>>> d = dict([(k,v) for k,v in d.iteritems() if v!=0])
>>> d
{'a':1,'c':1'}

もしPythonより大きいならば>=2.7
このような書き方もできます。

>>> d = {k:v for k,v in d.iteritems() if v !=0 }