亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python 3 中 .keys() 的大多數 Pythonic 替換

Python 3 中 .keys() 的大多數 Pythonic 替換

慕絲7291255 2021-06-04 16:53:48
我一直在考慮將我的 Python 2.7 項目轉換為 3。我發現我主要使用 .keys() 作為不必要的for x in d:具有相同的效果for in in d.keys():但是,我還了解到,在遍歷字典時,您不應該對其進行變異。這還沒有出現,因為我一直在使用 Python2.7 的 .keys() 來創建字典鍵的副本作為列表。Python 3 的 .keys() 版本創建的是視圖而不是副本,因此不能用于相同目的。2to3 將 d.keys() 轉換為 list(d.items()) 但我并不嚴格需要列表中的鍵。我已經看到 d.copy().keys() 建議,但我不明白為什么 (Python 3) .keys() 位是必要的。在 Python Docs 中它說在迭代字典時修改鍵的值是安全的,但前提是鍵集不改變那么“變異”是否僅指更改密鑰呢?大多數情況下,我只在迭代時更改字典值,但我發現某個地方有可能刪除當前鍵所以基本上我需要用任何東西替換 .keys() ,如果是這樣,最pythonic/高效的選項是什么?具體代碼(我在冒險游戲/互動小說引擎中重復效果/隨時間推移造成的傷害的一部分)是這樣的:def Age(beats) :    actions = []    for echo in echoes.keys() :        echoes[echo]['elapsed'] += beats        activations = echoes[echo]['elapsed']/echoes[echo]['interval']        while activations >= 1 :            actions.append(str(echoes[echo]['action']))            echoes[echo]['elapsed'] -= echoes[echo]['interval']            activations = echoes[echo]['elapsed']/echoes[echo]['interval']            try :                echoes[echo]['reps'] -= 1                if echoes[echo]['reps'] < 1 :                    del echoes[echo]                    break            except TypeError : #Will be raised if reps is Infinite                pass    char['Echoes'] = echoes    char.write()    return actions是的,我可能一個人在這里犯下各種風格指南的罪過。我是自學的,發現這個項目的所有好的實踐都太晚了。對不起,如果我讓你的眼睛流血了。
查看完整描述

2 回答

?
慕森卡

TA貢獻1806條經驗 獲得超8個贊

我建議創建一個需要刪除的鍵列表,然后在完成循環后刪除它們:


def Age(beats):

    to_remove = []

    actions = []

    for echo in echoes.keys():

        echoes[echo]['elapsed'] += beats

        activations = echoes[echo]['elapsed']/echoes[echo]['interval']

        while activations >= 1 :

            actions.append(str(echoes[echo]['action']))

            echoes[echo]['elapsed'] -= echoes[echo]['interval']

            activations = echoes[echo]['elapsed']/echoes[echo]['interval']

            try :

                echoes[echo]['reps'] -= 1

                if echoes[echo]['reps'] < 1 :

                    to_remove.append(echo)

                    break

            except TypeError : #Will be raised if reps is Infinite

                pass

    for echo in to_remove:

        del echoes[echo]

    char['Echoes'] = echoes

    char.write()

    return actions

我也認為它的可讀性稍微好一些.items():


for echo, value in echoes.items():

    value['elapsed'] += beats

    ...


查看完整回答
反對 回復 2021-06-16
?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

我已經看到 d.copy().keys() 建議,但我不明白為什么 (Python 3) .keys() 位是必要的。

你讀得還不夠仔細。由于d.copy().keys()創建了字典的副本然后從該副本創建鍵,因此它本質上指向字典和鍵的新“視圖”。

這基本上是它在 python 2.7 中所做的,因此它可以用于您的目的。

因此,在 python 2.7 中,直接從 dict 創建一個新列表并返回,而 python 3 直接指向該 dict 的鍵,這意味著如果它在迭代過程中發生變化,它將拋出并出錯。

您可以在 python 3 中解決此問題的另一種方法是:

for x in list(d):

因為這將返回一個在迭代過程中不會改變大小的“新”列表。


查看完整回答
反對 回復 2021-06-16
  • 2 回答
  • 0 關注
  • 222 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號