我有一个字符串列表,例如:

myList = ["paper", "Plastic", "aluminum", "PAPer", "tin", "glass", "tin", "PAPER", "Polypropylene Plastic"]

我想要这个结果(这是唯一可以接受的结果):
myList = ["paper", "Plastic", "aluminum", "tin", "glass", "Polypropylene Plastic"]

请注意,如果一个项目("Polypropylene Plastic")恰好包含另一个项目("Plastic"),我仍然希望保留这两个项目。因此,情况可能不同,但项目必须是字母匹配的字母,才能将其删除。
必须保留原始列表顺序。应删除该项的第一个实例之后的所有重复项。应保留第一个实例的原始案例以及所有非重复项的原始案例。
我已经搜索过了,只找到了满足一个需求或另一个需求的问题,而不是同时找到两个。

最佳答案

很难用列表理解(或以牺牲清晰度为代价)来编写代码,因为积累/记忆效应需要过滤掉重复项。
也不可能使用理解,因为它会破坏原始顺序。
带有循环和辅助字符串的经典方法,用于存储遇到的字符串的小写版本。仅当低基版本不在集合中时,才将字符串存储在结果列表中

myList = ["paper", "Plastic", "aluminum", "PAPer", "tin", "glass", "tin", "PAPER", "Polypropylene Plastic"]
result=[]

marker = set()

for l in myList:
    ll = l.lower()
    if ll not in marker:   # test presence
        marker.add(ll)
        result.append(l)   # preserve order

print(result)

结果:
['paper', 'Plastic', 'aluminum', 'tin', 'glass', 'Polypropylene Plastic']

使用set而不是set可以处理某些地区的细微“大小写”差异(如strasse/stra_e中的德语双“s”)。
编辑:这可以通过列表理解来实现,但它确实很糟糕:
marker = set()
result = [not marker.add(x.casefold()) and x for x in myList if x.casefold() not in marker]

它在.casefold()的输出上使用.lower()来调用这个函数(列表理解中的副作用,很少是好事…),并返回and不管什么。主要缺点是:
可读性
两次调用None一次用于测试一次用于存储在标记集中

08-25 06:40
查看更多