Python:删除列表中至少由同一列表中的一个其他字符串包含的字符串
我希望通过以下方式过滤我的字符串列表:如果同一列表中至少有另一个字符串“在”它中,我希望排除字符串。或者换一种说法:如果列表中没有其他相同的字符串,我希望维护字符串。如果可能的话,区分大小写应该在这里发挥作用 为了更清楚地说明这一点,请在下面找到一个示例: 我的“第一个”列表包含每个字符串:Python:删除列表中至少由同一列表中的一个其他字符串包含的字符串,python,list,Python,List,我希望通过以下方式过滤我的字符串列表:如果同一列表中至少有另一个字符串“在”它中,我希望排除字符串。或者换一种说法:如果列表中没有其他相同的字符串,我希望维护字符串。如果可能的话,区分大小写应该在这里发挥作用 为了更清楚地说明这一点,请在下面找到一个示例: 我的“第一个”列表包含每个字符串: elements =["tree","TREE","treeforest","water","waterfall&q
elements =["tree","TREE","treeforest","water","waterfall"]
应用解决方案后,我希望收到以下列表:
elements = ["tree","TREE","water"]
例如:tree
位于treefrest
中。因此,treefrest
被排除在我的列表之外。同样适用于水
和瀑布
。但是,tree
、tree
和water
应该被维护,因为它们中没有其他字符串
由于我想将其应用于“更大”的字符串列表,因此更有效的解决方案是首选
希望这是可以理解的。提前多谢!!非常感谢您的帮助
from copy import deepcopy
def remove_composite_words(e,elements):
temp = [x for x in elements if e in x]
temp = set(temp)
elements = list(set(elements).difference(temp))
return e,sorted(elements, key=len)
def keep_shortest_root(elements):
elements = deepcopy(elements)
elements = list(set(elements))
elements = sorted(elements, key=len)
if len(elements[0]) ==0:
elements = elements[1:]
results = []
e = elements[0]
while elements:
e,elements = remove_composite_words(e,elements)
results.append(e)
if elements:
e = elements[0]
return results
elements =["tree","TREE","treeforest","water","waterfall",'forestTREE','tree']
keep_shortest_root(elements)
这应该会回来
['tree', 'TREE', 'water']
工作原理:
函数remove\u composite\u words()
测试中的元素是否包含在列表中的任何其他元素中,并仅保存匹配的元素。然后从初始列表中删除匹配的元素
因此,如果您有元素'a'
和列表['a','aa','b','c']
,函数将返回'a'
和列表['b','c']
keep_shortest_root()
将remove_composite_words()
应用于初始列表,然后应用于转换后的列表(从remove_composite_words()
输出),直到没有剩余的单词为止
请注意,keep_shortest_root()
首先从输入列表中获取唯一的单词,然后按长度排序。这与remove\u composite\u words()
从初始列表中删除匹配的单词这一事实相结合,使得算法运行得更快,因为比较的次数会随着迭代次数的减少而减少
这应该会回来
['tree', 'TREE', 'water']
工作原理:
函数remove\u composite\u words()
测试中的元素是否包含在列表中的任何其他元素中,并仅保存匹配的元素。然后从初始列表中删除匹配的元素
因此,如果您有元素'a'
和列表['a','aa','b','c']
,函数将返回'a'
和列表['b','c']
keep_shortest_root()
将remove_composite_words()
应用于初始列表,然后应用于转换后的列表(从remove_composite_words()
输出),直到没有剩余的单词为止
请注意,
keep_shortest_root()
首先从输入列表中获取唯一的单词,然后按长度排序。这与从初始列表中删除匹配单词的事实相结合,使得算法运行得更快,因为比较的次数会随着迭代次数的减少而减少。找到了一个比已经提供的更简单的解决方案,我想我可以插手
def Remove_Subset(List):
ListCopy=List
for Element1 in List:
for Element2 in List:
if (Element1 in Element2) and (Element1!= Element2):
ListCopy.remove(Element2)
return(ListCopy)
elements =["treeforest","tree","TREE","treeforest","water","waterfall","tree"]
print(Remove_Subset(elements))
>>> ['tree', 'TREE', 'water']
找到了一个比已经提供的更简单的解决方案,我想我可以插手
def Remove_Subset(List):
ListCopy=List
for Element1 in List:
for Element2 in List:
if (Element1 in Element2) and (Element1!= Element2):
ListCopy.remove(Element2)
return(ListCopy)
elements =["treeforest","tree","TREE","treeforest","water","waterfall","tree"]
print(Remove_Subset(elements))
>>> ['tree', 'TREE', 'water']
这是对我在评论中给出的答案的解释
我使用了以下代码:
new_elements = list(filter(lambda item: not any(elem in item for elem in elements if elem != item), elements))
这将产生:
['tree', 'TREE', 'water']
我不知道您对Python生成器表达式和过滤器了解多少,所以我将尝试解释一下 是一个Python内置函数,它在提供的iterable(如列表等)中的每个项上使用一个函数。在我们的例子中,功能如下:
lambda item: not any(elem in item for elem in elements if elem != item)
此函数从列表中获取一个项(item
),然后迭代列表中的每个元素(对于elem in elements
),对于每个元素(elem
)检查该元素是否在字符串中(item
)。请注意,如果元素!=项目,因为我们不想将其与自身进行比较
函数any
只是不断迭代,直到返回的表达式为True
,或者到达末尾。如果存在任何匹配项,any
返回True
,但要让filter
删除此项,我们需要返回False
,因此我们将any
的输出反转
我们还将传递到我们的列表(元素
),并将结果从过滤器
转换到另一个列表
注意:使用
any
而不是针对每个其他项目迭代每个项目的好处是,在查找匹配项的情况下,我们不必迭代整个列表:any
在该点返回。从理论上讲,这可能比两个嵌套for循环(没有break
语句)更快。这是我在评论中给出的答案的解释
我使用了以下代码:
new_elements = list(filter(lambda item: not any(elem in item for elem in elements if elem != item), elements))
这将产生:
['tree', 'TREE', 'water']
我不知道您对Python生成器表达式和过滤器了解多少,所以我将尝试解释一下 是一个Python内置函数,它在提供的iterable(如列表等)中的每个项上使用一个函数。在我们的例子中,功能如下:
lambda item: not any(elem in item for elem in elements if elem != item)
此函数从列表中获取一个项(item
),然后迭代列表中的每个元素(对于elem in elements
),对于每个元素(elem
)检查该元素是否在字符串中(item
)。请注意,如果元素!=项目,因为我们不想将其与自身进行比较
函数any
只是不断迭代,直到返回的表达式为True
,或者到达末尾。