![](/img/trans.png)
[英]Most efficient way to remove duplicates from Python list while preserving order and removing the oldest element
[英]Removing duplicates from list of lists each element compared, preserving order
我在 Python 中有一个列表列表,想要删除每个被比较元素的重复项,是的,我(最关心)列表的顺序。
我已经看过大多数关于堆栈溢出的解决方案。 例如, 这里的解决方案投票不比较列表列表的元素,并且对于给定的用例会很好,前提是它已排序。 但是,我正在寻找的是:
有什么可用
s1 = ['Lucifer', 'Ella']
s2 = ['Lucifer', 'Eve']
s3 = ['Chloe', 'Lucifer']
s4 = ['Lucifer', 'Linda']
需要什么
正如我所说,关心顺序,从每个列表中删除重复项(这就是列表中缺少“Lucifer”的原因)并只获取唯一的..
['Ella', 'Eve', 'Chloe', 'Linda']
注意:它并不总是第一个在列表中通用的元素,例如在 s4 中它可以是“Amenadiel”。 现在让我们假设要比较的列表长度始终为 2。
我试过什么
list((set(s1) ^ set(s2) ^ set(s3) ^ set(s4)) ^ (set(s1) & set(s2) & set(s3) & set(s4)))
上面的输出是['Chloe', 'Eve', 'Linda', 'Ella', 'Lucifer']
这不是预期的(如上所述!)。
这适用于两个或三个列表,但不适用于四个列表。
请帮忙!
TIA。
您可以首先使用 Counter 查找重复项,然后在第二遍中将它们过滤掉:
from collections import Counter
s1 = ['Lucifer', 'Ella']
s2 = ['Lucifer', 'Eve']
s3 = ['Chloe', 'Lucifer']
s4 = ['Lucifer', 'Linda']
lists = [s1, s2, s3, s4]
flattened = [item for sublist in lists for item in sublist]
counts = Counter(flattened)
deduped = [x for x in flattened if counts[x] <= 1]
print(deduped) # ['Ella', 'Eve', 'Chloe', 'Linda']
如果您的目标是只删除每个列表中的元素:
s1 = ['Lucifer', 'Ella']
s2 = ['Lucifer', 'Eve']
s3 = ['Chloe', 'Lucifer']
s4 = ['Lucifer', 'Linda']
lists = [s1, s2, s3, s4]
flattened = [item for sublist in lists for item in sublist]
seen = set.intersection(*map(set, lists))
deduped = []
for item in flattened:
if item in seen:
continue
seen.add(item)
deduped.append(item)
print(deduped) # ['Ella', 'Eve', 'Chloe', 'Linda']
from collections import Counter
from itertools import chain
s1 = ['Lucifer', 'Ella']
s2 = ['Lucifer', 'Eve']
s3 = ['Chloe', 'Lucifer']
s4 = ['Lucifer', 'Linda']
# count the occurrences
counts = Counter(chain(s1, s2, s3, s4))
# remove duplicates
result = [name for name in chain(s1, s2, s3, s4) if counts[name] < 2]
print(result)
输出
['Ella', 'Eve', 'Chloe', 'Linda']
更新
如果您想要没有出现在所有列表中的那些,请执行以下操作:
from collections import Counter, OrderedDict
from itertools import chain
s1 = ['Lucifer', 'Ella']
s2 = ['Lucifer', 'Eve']
s3 = ['Chloe', 'Lucifer']
s4 = ['Amenadiel', 'Linda']
all_ls = [s1, s2, s3, s4]
# count the occurrences
counts = Counter(chain.from_iterable(all_ls))
# remove duplicates i.e do not appear in all lists
names = list(OrderedDict.fromkeys(chain.from_iterable(all_ls)))
result = [name for name in names if counts[name] < len(all_ls)]
print(result)
输出
['Lucifer', 'Ella', 'Eve', 'Chloe', 'Amenadiel', 'Linda']
一种方法是最初将所有列表相加。 然后,将此列表转换为字典。 此后,将此临时字典转换为列表。
s1 = ['Lucifer', 'Ella']
s2 = ['Lucifer', 'Eve']
s3 = ['Chloe', 'Lucifer']
s4 = ['Lucifer', 'Linda']
s_all = s1 + s2 + s3 + s4 # Concatenate all lists
temp_dict = dict.fromkeys(s) # Create a dictionary with keys from list `s_all`
s_no_dupes = list(temp_dict) # Convert the dictionary to a list
print(s_no_dumpes)
['Lucifer', 'Ella', 'Eve', 'Chloe', 'Linda']
注意:这将删除所有重复项,但如果您希望它们按顺序排列,则必须使用 Python 3.6 或更高版本,因为字典键是从 Python 3.6 开始排序的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.