繁体   English   中英

从列表列表中删除每个元素比较的重复项,保留顺序

[英]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']

另一种使用Counterchain的替代解决方案:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM