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
,或者到达末尾。