我有一个字符串列表,例如:
myList = ["paper", "Plastic", "aluminum", "PAPer", "tin", "glass", "tin", "PAPER", "Polypropylene Plastic"]
我想要这个结果(这是唯一可以接受的结果):
myList = ["paper", "Plastic", "aluminum", "tin", "glass", "Polypropylene Plastic"]
请注意,如果一个项目(“聚丙烯塑料”
)恰好包含另一个项目(“塑料”
),我仍然想保留这两个项目。因此,情况可能不同,但该项目必须逐个字母匹配,才能将其删除。
必须保留原来的列表顺序。该项目的第一个实例之后的所有重复项都应删除。应保留该一审的原案,以及所有非重复项目的原案。
我进行了搜索,但只找到了满足一种需求或另一种需求的问题,而不是两者兼而有之。
最佳答案
由于您需要过滤掉重复项的累积/内存效应,因此很难通过列表理解(或以清晰度为代价)来编写代码。
也不可能使用 set
理解,因为它破坏了原始顺序。
带有循环和辅助 set
的经典方法,您可以在其中存储遇到的字符串的小写版本。仅当小写版本不在集合中时才将字符串存储在结果列表中
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']
使用 .casefold()
而不是 .lower()
可以处理某些语言环境中细微的“大小写”差异(例如 Strasse/中的德语双“s”大街)。
编辑:是可以通过列表推导来做到这一点,但这真的很 hacky:
marker = set()
result = [not marker.add(x.casefold()) and x for x in myList if x.casefold() not in marker]
它在 set.add
的 None
输出上使用 and
来调用此函数(列表理解中的副作用,很少是好的thing...),并返回 x
无论如何。主要缺点是:
- 可读性
- 事实上
casefold()
被调用了两次,一次用于测试,一次用于存储在标记集中
关于python - 如何从列表中删除不区分大小写的重复项,同时保持原始列表顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48283295/