python - 如何从列表中删除不区分大小写的重复项,同时保持原始列表顺序?

标签 python list

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

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.addNone 输出上使用 and 来调用此函数(列表理解中的副作用,很少是好的thing...),并返回 x 无论如何。主要缺点是:

  • 可读性
  • 事实上 casefold() 被调用了两次,一次用于测试,一次用于存储在标记集中

关于python - 如何从列表中删除不区分大小写的重复项,同时保持原始列表顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48283295/

相关文章:

python - Django self.cleaned_data Keyerror

python - Pandas :将行值设置为与索引号对应的字母表中的字母?

python - 属性错误 : 'module' object has no attribute 'main' for tf. app.run()

Python:如何用第二个数字减去列表中的第一个数字

python - 按第二个值对嵌套列表进行排序

Python 对象列表更新

python - 如何使用 PyList 返回 Python C API 扩展中的整数列表?

python - Python 的 argparse 模块中具有混合类型 args 输入的参数解析器

r - 在列表上应用 paste0 函数

python - 如何忽略转义\python 列表?