删除列表中没有子字符串的项目的优雅方式 [英] Elegant way to delete items in a list which do not has substrings that appear in another list
问题描述
最近我遇到了这个问题:
Recently I encountered this problem:
说有一个我要处理的东西的清单:
Say there is a list of something I want to process:
process_list=["/test/fruit/apple","/test/fruit/pineapple","/test/fruit/banana","/test/tech/apple-pen","/test/animal/python","/test/animal/penguin"]
我想使用其他列表排除某些内容,例如:
And I want to exclude something using another list, for instance:
exclude_list=["apple","python"]
在将exclude_list应用于它之后,process_list应该是这样的(任何包含子项的process_list项:
The process_list should be like this after I apply the exclude_list to it( any process_list item that contains a sub:
["/test/fruit/banana","/test/animal/penguin","/test/fruit/pineapple"]
,或者如果exclude_list为:
exclude_list=["pen","banana"]
or if the exclude_list is:
exclude_list=["pen","banana"]
在应用过滤器后,process_list应该是这样:
The process_list should be this after apply the filter:
["/test/fruit/apple","/test/fruit/pineapple","/test/animal/python"]
所以我最初尝试的是:
for item in exclude_list:
for name in (process_list):
if item in name:
process_list.remove(name)
当然这是行不通的,因为不允许在使用for
循环对其进行迭代时从列表中删除元素.该代码只删除了第一个匹配项,然后停止了.
Of course this didn't work because removing elements from the list while iterating over it using a for
loop is not permitted. The code only removed the first match and then stopped.
因此,我想出了一种方法来处理另一个列表:
So then I came up a way to do this with another list:
deletion_list=[] #Track names that need to be deleted
for item in exclude_list:
for name in (process_list):
if item in name:
deletion_list.append(name)
# A list comprehension
process_list=[ x for x in process_list if x not in deletion_list ]
它有效,但是我的胆量告诉我,也许有一种更优雅的方法.现在需要另一个列表来存储需要删除的名称.有什么想法吗?
It works, but my guts tell me there may be a more elegant way. Now it need s another list to store the name need to be deleted. Any ideas?
推荐答案
You may use the list comprehension expression using all()
filter as:
# Here: `p` is the entry from `process_list`
# `e` is the entry from `exclude_list`
>>> [p for p in process_list if all(e not in p for e in exclude_list)]
['/test/fruit/banana', '/test/animal/penguin']
关于您的声明:
Regarding your statement:
当然这是行不通的,因为不允许使用for循环在列表上进行迭代时从列表中删除元素.该代码只删除了第一个匹配项,然后停止了.
Of course this didn't work because removing elements from the list while iterating over it using a for loop is not permitted. The code only removed the first match and then stopped.
您可以按以下方式遍历列表的副本:
You could have iterate over the copy of the list as:
for item in list(exclude_list): # OR, for item in exclude_list[:]:
# ^-- Creates new copy ----------------------------^
这篇关于删除列表中没有子字符串的项目的优雅方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!