簡體   English   中英

Python - 刪除列表中前兩次出現的元素

[英]Python - Removing first two occurrences of element in list

這個 function 的目標是刪除列表中前兩次出現的 n。

下面是我寫的代碼,但幾個小時后我仍然弄錯了。 一位朋友建議我不要在迭代時編輯列表。 但是,我仍然卡住了。

def remove_first_two(list,n):
    if list == []:
        return []
    else:
        count = 0
        for ele in list:
            if ele == n:
                list.remove(ele)
                count += 1
                if count == 2:
                    break
    return list

list = [1,2,2,3]
print(remove_first_two(list,2)) => [1,2,3] instead of [1,3]

list.remove與 try-except 一起使用兩次。 這將刪除前兩個條目。 復雜度O(n)

list_a = [1,2,3,4]

try:
    list_a.remove(n)
    list_a.remove(n)
    # run a loop too, if it's more than 2
except:
    pass

您可以嘗試查找所有索引和刪除:

a = [1,2,3,2,3,2,4]
indices = [i for i, x in enumerate(a) if x == 2]
print(indices)

[1, 3, 5]
del a[indices[0]], a[indices[1]]
print(a)

[1, 3, 2, 2, 4]

首先,不要使用“list”作為 Python 中的關鍵字。使用其他名稱,例如“alist”。 下面的代碼做你想做的,並保持你已有的基本形式。 您當然也可以使用 built-in.remove() 方法。

def remove_first_two(alist, n):
    if alist == []:
        return []
    else:
        count = 0
        while count < 2:
            for ele in alist:
                if ele == n:
                    alist.remove(ele)
                    count += 1
    return alist

alist = [1,2,2,3]
print(remove_first_two(alist,2)) # Output -> [1,3]

當您的朋友說“不要在迭代時編輯列表”時,他/她是對的,他/她的意思是您應該一起創建另一個列表。 您要執行的操作如下:

def remove_first_two(list, n):
    if list == []:
        return []
    else:
        new_list = []
        count = 0
        for ele in list:
            if ele == n:
                if count >= 2:
                    new_list.append(ele)

                count += 1
            else:
                new_list.append(ele)

    return new_list

但是,請注意,您可以使用一些內置函數來讓您的生活更輕松:

list.remove(x)

從列表中刪除第一個值等於 x 的項目。 如果沒有這樣的項目,它會引發 ValueError。

因此,您可以更簡單地執行以下操作:

def remove_first_two(list, n):
    if list == []:
        return []

    for _ in range(2):
        if n in list:
            list.remove(n)

    return list

如果您在迭代時更改列表,Python 會更新列表。

在您使用list = [1,2,2,3]時,刪除list[1]並且Python 更新list = [1,2,3] 現在 Python 知道您已經迭代到索引 1 並從現在包含3的索引 2 繼續。 所以 Python只遇到一次 2

所以聽從你朋友的建議,不要在迭代時編輯列表:)

現在您可以使用 Python 的內置list.remove(element)刪除元素的第一次出現。 重復 2 次以獲得所需的 output。

也 O(n) 與一個單一的解析。

def remove_first_two(mylist,n):
    counter = 0
    def myfilter (i):
        nonlocal counter,n
        if counter > 2:
            return True
        else: 
            counter += 1
            return (i != n)
    return (list(filter(myfilter,mylist)))

這也可以在 python 3.8 中使用列表理解中的賦值表達式來完成:

data = [1,2,3,2,3,2,4]

count = 2
num = 2

[x for x in data if x != num or (count:=count-1) < 0]

結果:

[1, 3, 2, 2, 4]

這是您的程序不起作用的原因:當您刪除一個元素時, for循環移動到下一個元素,但通過“繼續”它實際上跳過了現在占據已刪除元素的 position 的元素。 它會跳過您刪除的元素之后的元素。

在刪除元素時迭代列表的正確方法是通過使用 while 循環而不是 for 循環來明確索引級數,並且在刪除元素時不增加索引:

i = 0 
while i < len(my_list):
    if condition:
        my_list.pop(i)
    else:
        i += 1

但是,在您的情況下,這些都不是必需的! 請注意,當您使用my_list.remove(ele)時,您沒有像使用my_list.pop(i)那樣提供索引,因此 Python 必須搜索與ele匹配的第一個元素。 雖然單獨使用remove會比pop慢,但是這里remove允許你完全不用任何循環,只需要做兩次my_list.remove(n)

最后一點:如果您的列表中匹配n的元素少於兩個,則兩個my_list.remove(n)命令之一將返回ValueError 您可以考慮此異常,知道如果發生這種情況,您的列表已准備就緒,無需采取進一步行動。

所以你需要的代碼是:

try:
    my_list.remove(n)
    my_list.remove(n)
except ValueError:
    pass

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM