我有一个像下面的列表
L = [[1,2],[1,3],[1,4],[2,1],[2,5],[3,1],[3,2]]
输出应该是
[[1,2],[1,3],[1,4],[2,5],[3,2]]
请注意,在对和元素的顺序必须被保留。 换句话说,由于要素订单需要保留的对,以及我不能对列表进行排序。 例如,我需要的最后一个元素[3,2]被保存下来。 如果我对它们进行排序和删除重复这将被更改为[2,3],我不想要的。 此外,当我说我需要删除重复[1,2]或[2,1]被认为是重复的,我希望保留这个[1,2]。
这种工作原理类似于从常规列表,同时保留顺序删除重复 ,但我们需要做一些事情不是子列表可哈希和子列表是不相关的顺序。
我们可以用冷冻组,可以同时解决这两个问题。
>>> lst = [[1,2],[1,3],[1,4],[2,1],[2,5],[3,1],[3,2]]
>>> seen = set()
>>> result = []
>>>
>>> for x in lst:
... s = frozenset(x)
... if s not in seen:
... result.append(x)
... seen.add(s)
...
>>> result
[[1, 2], [1, 3], [1, 4], [2, 5], [3, 2]]
该unique_everseen
在功能itertools
食谱中的文档不正是你所需要的:
>>> lst = [[1,2],[1,3],[1,4],[2,1],[2,5],[3,1],[3,2]]
>>> list(unique_everseen(lst, key=frozenset))
[[1, 2], [1, 3], [1, 4], [2, 5], [3, 2]]
其基本思路是,它让一组迄今所看到的所有值,并跳过这已经在设置的任何值。
该key
功能的工作方式相同,如sort
, max
等,在解释的排序HOWTO 。 你想有不同的顺序匹配相同的价值观两个列表,所以我们需要比较集中的每个列表的价值观,而不是名单本身。 (我们需要的原因frozenset
,而不是set
是set
是可变的,因此不能存储在一组。)
如果你有在你的子表超过2元,该问题将是不明确的。 如果你有,比如说, [1, 1, 2]
和[1, 2, 2]
你希望它们被认为是重复的,或不?
- 如果是的话:那你对待他们一组,所以使用
key=frozenset
。 - 如果没有:那你把它们当作一个多集。 多集的最好的Python的实现是
collections.Counter
,但没有FrozenCounter
(和建立一个只用于此目的可能是矫枉过正)。 您可以模拟一个在几个方面: -
key=lambda sublist: frozenset(Counter(sublist).items())
-
key=lambda sublist: sorted(Counter(sublist).items())
-
key=lambda sublist: tuple(sorted(sublist))
由于您最初的想法是排序的子表,其中,因为你需要为原始值,结束了,只是不能接受没有排序的价值,我认为最后的这些选项是最有可能是你想要的,但这是真的还是只是一个猜测。
您可以复制并粘贴文档到你的代码的功能:
from itertools import *
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
......或者安装第三方库more_itertools
并使用其unique_everseen
从那里。 或不同的第三方库toolz
有一个名为同等功能unique
。