簡體   English   中英

從列表中刪除最后出現的包含 substring 的元素

[英]Remove last occurrence of element containing substring from a list

所以說我有,list1 = ['the dog', 'the cat', 'cat dog', 'the dog ran home']

和 sub_string = '狗'

我怎樣才能返回 list2 = ['the dog', 'the cat', 'cat dog']

即,返回一個刪除了最后一次出現的 ZE83AED3DDF4667DEC0DAAAACB2BB3BE0BZ 的列表?

在這里沒有內置功能對您有很大幫助,因為在list中掃描 substring 不是受支持的功能,並且以相反的順序執行此操作會加倍困難。 列表推導也不會起到太大作用,因為讓它們有足夠的狀態來識別您何時發現您的針將涉及向列表推導添加副作用,這使得它變得神秘並違反了函數式編程工具的目的。 所以你被困在自己的循環中:

list2 = []
list1iter = reversed(list1)  # Make a reverse iterator over list1
for item in list1iter:
    if sub_string in item:   # Found item to remove, don't append it, we're done
        break
    list2.append(item)       # Haven't found it yet, keep item
list2.extend(list1iter)      # Pull all items after removed item
list2.reverse()              # Put result back in forward order

在線嘗試!

另一種方法是按索引掃描,允許您del它; 如果您想就地修改list1而不是創建一個新list ,這可能是一個更好的解決方案:

for i, item in enumerate(reversed(list1), 1):
    if sub_string in item:
        del list1[-i]
        break

在線嘗試!

該解決方案適用於通過簡單地將所有對list1的引用更改為list2並在循環之前添加list2 = list1[:]來制作新副本。

在這兩種情況下,您都可以通過在for上放置else:塊來檢測是否找到了某個項目; 如果else塊觸發,你沒有break ,因為在任何地方都找不到sub_string

問題陳述是:刪除以 ZE83AED3DDF4667DEC0DAAAACB2BB3BE0BZ 作為查詢的元素

所以,正如我推斷的那樣,它有兩個步驟。

  1. 使用 substring 查找元素。
  2. 移除元素。

對於模式匹配,我們可以使用re模塊(我們可以使用in以及 ShadowRanger 的答案中提到的)

import re

pattern = re.compile('the dog') # target pattern 
my_list = ['the dog', 'the cat', 'cat dog', 'the dog ran home'] # our list
my_list = enumerate(my_list) # to get indexes corresponding to elemnts i.e. [(0, 'the dog'), (1, 'the cat'), (2, 'cat dog'), (3, 'the dog ran home')]
elems = list(filter(lambda x: pattern.search(x[1]), my_list) # match the elements in the second place and filter them out, remember filter in python 3.x returns an iterator
print(elems) # [(0, 'the dog'), (3, 'the dog ran home')]
del my_list[elems[-1][0]] # get the last element and take the index of it and delete it.

編輯

正如 ShadowRunner 所建議的那樣,我們可以使用帶有 if 語句的列表解析來優化代碼,而不是filter function。

elems = [i for i, x in enumerate(my_list) if pattern.search(x)]

您可以分兩步完成:

  1. 查找最后一次出現的索引。
  2. 返回與該索引不匹配的所有元素。

例子:

needle = 'the dog'
haystack = ['the dog', 'the cat', 'cat dog', 'the dog ran home']

last = max(loc for loc, val in enumerate(haystack) if needle in val)
result = [e for i, e in enumerate(haystack) if i != last]

print(result)

Output

['the dog', 'the cat', 'cat dog']

有關查找最后一次出現的索引的更多詳細信息,請參閱

list1 = ['the dog', 'the cat','the dog me', 'cat dog']
sub_string = 'the dog'

for i in list1[::-1]:
    print(i)
    if sub_string in i:
        list1.remove(i)
        break

output ['狗','貓','狗我','貓狗']

一種解決方案是以相反的順序遍歷輸入並在反向列表中找到索引。 之后,使用索引對輸入list1進行切片。

idx = next(i for i, s in enumerate(reversed(list1), 1) if sub_string in s)
list2 = list1[:-idx]  # If in-place updates are intended, use `del list1[-idx:]` instead

暫無
暫無

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

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