在遍歷他們不能修改的集合。
大約有這幾個方面:
- (0)重新考慮你的設計,看看你是否需要這樣做。
- (1)不要修改集合;相反,建立一個新的過濾收集。
- (2)不要遍歷集合;而是迭代集合的副本
- (2.5)對於字典,迭代鍵的副本並顯式獲取值。
請注意,儘管迭代了項目,但您已經明確地獲取了值,因此沒有理由在此處使用#2。
下面是另外兩個的實現:
new_img_dict = {}
for key in img_dict:
if (time.time()-float(img_dict[key])) >= stale_img:
logger.debug('STALE IMAGE FROM '+hexlify(key)+ ' - GOT CLOSED NOW!')
data_upload = True
else:
new_img_dict[key] = img_dict[key]
img_dict = new_img_dict
或者:
for key in img_dict.keys():
if (time.time()-float(img_dict[key])) >= stale_img:
logger.debug('STALE IMAGE FROM '+hexlify(key)+ ' - GOT CLOSED NOW!')
del img_dict[key]
data_upload = True
(如果你想這是Python 3的兼容,而不是img_dict.keys()
,做img_dict.keys()[:]
。)
那麼,你如何在兩者之間進行選擇?
第一個通常更容易推理 - 通常,不可變對象和純操作很容易推理。例如,如果您在某個地方拋出異常,則img_dict
將始終具有原始版本或完整版本,而不是介於兩者之間的一半。當然,你不必思考在迭代它的時候改變什麼的意思。但是,在極少數情況下,很難將「將所有foo」刪除的算法轉換爲「copy foo not foo」算法。
第一個是通常也更容易改寫爲理解(或像filter
高階函數的調用),變成一個發電機,重構拉出獨立的功能,等等
對於性能,第一個通常會更快,使用更少的內存,如果你過濾了很多值,而第二個通常會更好,如果你保持大多數價值。 (對於不同的收集類型,截止點是不同的,通常情況下,它很少重要,如果是這樣的話,應該寫兩種方式和配置文件。)
回到#0,我認爲它可能適用於這種情況。你正在穿過所有的鑰匙,看看是否有太舊的鑰匙,以便將它們移除。如果您使用了排序列表或優先級隊列,則不必這樣做。現在,如果您需要更頻繁地使用集合作爲dict
而不是您需要刷新舊值,那麼您可能會獲得更多的成本,而不是從更改數據結構中獲益。但爲什麼不都有?如果你有按鍵的排序列表,在字典映射鍵到值之上,那麼你可能只是這樣做:
for key in img_sorted_key_list:
if time.time() - float(key) > stale_img:
break
del img_dict[key]
或者更簡單地說:
stale_time = time.time() - stale_img
for key in itertools.takewhile(lambda key: float(key) < stale_time,
img_sorted_key_list):
del img_dict[key]
而且你可以換了排序的關鍵列表和字典一起成爲一個不錯的Cache
類或東西。
嘗試'img_dict.items()' – JBernardo
這不是你的問題,但你爲什麼要在img_dict.iteritems使用'關鍵,值():'的',而不是在img_dict鍵:' ,假設你沒有在任何地方使用'value',並且實際上明確地在做'img_dict [key]'? – abarnert