第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

如何改變被迭代的容器?

如何改變被迭代的容器?

茅侃侃 2022-06-22 16:21:34
在 python 中,哪些容器在迭代期間正確支持突變?例如:container = [1, 2, 3, 4]for i in container:    print(i)    if i == 2:        container.append(8)輸出1 2 3 4 8(可以在迭代期間附加列表)。但是,如果我.append(8)用.remove(1)輸出代替1 2 4(即元素3被跳過)。似乎列表迭代超出了索引而不是元素,因此只有后續(xù)列表項(而不是先前的列表項)可以在迭代期間安全地刪除。標(biāo)準(zhǔn)庫中是否有任何容器允許在迭代期間添加和刪除元素,其行為是:新元素確實(shí)會被迭代(對于list.append),移除的元素隨后不會被迭代,一個元素是否被迭代(或不被迭代)永遠(yuǎn)不會受到其他元素的添加/刪除的影響。我想到的應(yīng)用程序是事件回調(diào)的注冊表。觸發(fā)時,我希望回調(diào)能夠急切地注冊或取消注冊同一事件的其他回調(diào)。(例如,如果我迭代了容器的臨時副本,我需要等待事件再次觸發(fā),然后更改開始生效。)
查看完整描述

2 回答

?
青春有我

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超8個贊

list您可以通過使用適當(dāng)?shù)姆椒▽?shí)現(xiàn)對其進(jìn)行子類化來自定義行為,remove當(dāng)被刪除的索引小于當(dāng)前迭代器索引時,該方法會減少迭代器指向的索引:


from weakref import WeakSet


class IterList:

    def __init__(self, lst):

        self.list = lst

        self.index = 0


    def __next__(self):

        if self.index == len(self.list):

            raise StopIteration

        value = self.list[self.index]

        self.index += 1

        return value


class List(list):

    iterators = WeakSet()


    def __iter__(self):

        iterator = IterList(self)

        self.iterators.add(iterator)

        return iterator


    def remove(self, item):

        index = super().index(item)

        for iterator in self.iterators:

            if index < iterator.index:

                iterator.index -= 1

        del self[index]

以便:


container = List((1, 2, 3, 4))

for i in container:

    if i == 2:

        container.remove(1)

    for j in container:

        print(i, j)

輸出:


1 1

1 2

1 3

1 4

2 2

2 3

2 4

3 2

3 3

3 4

4 2

4 3

4 4


查看完整回答
反對 回復(fù) 2022-06-22
?
holdtom

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超10個贊

您要詢問的行為是所涉及的迭代器的實(shí)現(xiàn)細(xì)節(jié)。正如您所注意到的,該list_iterator類型使用內(nèi)部索引,因此刪除已訪問的元素會導(dǎo)致問題,因?yàn)樗鼤牧斜碇兴泻罄m(xù)值的索引。


我的建議是您實(shí)際上并沒有從列表中刪除任何值。相反,將它們添加到另一個容器中,也許是一個set(如果它們是可散列的)。這假設(shè)值是唯一的。但如果不是,您可能會在使用任何方法從列表中刪除它們時遇到問題。


container = [1, 2, 3, 4]

removed = set()

for i in container:

    if i not in removed:         # skip values that have been "removed"

        print(i)

        if i == 2:

            removed.add(1)       # since we've already visited 1, this has no real effect

            removed.add(3)       # this does work though, we won't print the 3

            container.append(8)  # additions of new elements work as normal

正如評論所暗示的那樣,該循環(huán)帶有 print out 1、2、4和8.


查看完整回答
反對 回復(fù) 2022-06-22
  • 2 回答
  • 0 關(guān)注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號