国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中遍歷字典過程中更改元素導(dǎo)致異常的解決方法

2020-01-04 17:28:24
字體:
供稿:網(wǎng)友
這篇文章主要介紹了Python中遍歷字典過程中更改元素導(dǎo)致錯誤的解決方法,針對增刪元素后出現(xiàn)dictionary changed size during iteration的異常解決做出討論和解決,需要的朋友可以參考下
 

先來回顧一下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

 

執(zhí)行結(jié)果:

##########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

嗯,然后我們進(jìn)入“正題”--

一段關(guān)于Python字典遍歷的“爭論”....
先摘抄下:

#這里初始化一個dict>>> d = {'a':1, 'b':0, 'c':1, 'd':0}#本意是遍歷dict,發(fā)現(xiàn)元素的值是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#結(jié)果拋出異常了,兩個0的元素,也只刪掉一個。>>> d{'a': 1, 'c': 1, 'd': 0}>>> d = {'a':1, 'b':0, 'c':1, 'd':0}#d.keys() 是一個下標(biāo)的數(shù)組>>> 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}#結(jié)果也是對的>>>#這里初始化一個dict>>> d = {'a':1, 'b':0, 'c':1, 'd':0}#本意是遍歷dict,發(fā)現(xiàn)元素的值是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#結(jié)果拋出異常了,兩個0的元素,也只刪掉一個。>>> d{'a': 1, 'c': 1, 'd': 0} >>> d = {'a':1, 'b':0, 'c':1, 'd':0}#d.keys() 是一個下標(biāo)的數(shù)組>>> 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}#結(jié)果也是對的>>>

其實這個問題本來很簡單,就是說如果遍歷一個字典,但是在遍歷中改變了他,比如增刪某個元素,就會導(dǎo)致遍歷退出,并且拋出一個dictionary changed size during iteration的異常.
解決方法是遍歷字典鍵值,以字典鍵值為依據(jù)遍歷,這樣改變了value以后不會影響遍歷繼續(xù)。
但是下面又有一位大神拋出高論:

首先,python 是推薦使用迭代器的,也就是 for k in adict 形式。其次,在遍歷中刪除容器中的元素,在 C++ STL 和 Python 等庫中,都是不推薦的,因為這種情況往往說明了你的設(shè)計方案有問題,所有都有特殊要求,對應(yīng)到 python 中,就是要使用 adict.key() 做一個拷貝。最后,所有的 Python 容器都不承諾線程安全,你要多線程做這件事,本身就必須得加鎖,這也說明了業(yè)務(wù)代碼設(shè)計有問題的.

但由“遍歷中刪除特定元素”這種特例,得出“遍歷dict的時候,養(yǎng)成使用 for k in d.keys() 的習(xí)慣”,我覺得有必要糾正一下。在普通的遍歷中,應(yīng)該使用 for k in adict。
另外,對于“遍歷中刪除元素”這種需求,pythonic 的做法是 adict = {k, v for adict.iteritems() if v != 0} 或 alist = [i for i in alist if i != 0]

這個寫法讓我眼前一亮:怎么還有這個語法?
再仔細(xì)一看,他可能是這個意思:

#!/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 = bdel bprint 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 = bdel bprint a

不知道對不對。
因為這個寫法一開始讓我猛然想到三元操作符,仔細(xì)一看才發(fā)現(xiàn)不是,以前Goolge到有個解決方案

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

val>65是個邏輯表達(dá)式,返回0或者1,剛好作為前面那個元組的ID來取值,實在是太妙了。。。
不過在Google的資料里面還有一個版本

#V1 if X else V2s = Nonea = "not null" if s == None else sprint a#'not null'

后來發(fā)帖在華蟒用戶組(中文Python技術(shù)郵件列表)中提到后眾多大神解答如下:

>>> 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 }
 

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 益阳市| 沂源县| 阿城市| 雅江县| 赣榆县| 古交市| 丰宁| 永寿县| 遵义市| 达州市| 乐平市| 华亭县| 新沂市| 醴陵市| 昌都县| 容城县| 灵宝市| 中方县| 广东省| 都昌县| 富阳市| 法库县| 北京市| 东乌珠穆沁旗| 南澳县| 高邑县| 高台县| 鄱阳县| 杨浦区| 宾川县| 苍梧县| 托克托县| 墨竹工卡县| 邵阳市| 西充县| 康马县| 台前县| 泾川县| 辰溪县| 巢湖市| 台中市|