从排列列表中获取所有唯一组合
Get all unique combinations from list of permutations
TL/DR
给定 X = {(A,B),(B,C),(D,E),(B,A),(C,B)}
(其中 X
是 set
)
如何过滤显示唯一组合(而不是唯一排列)的子元组,使得 X
变为
{(A,B),(B,C),(D,E))}
更长的形式
这里的大多数 combination/permutation 问题有点反问题。
我有一组元组(外元组),其中每个元组有2个元素,都是元组(内元组),每个子元组有两个元素,都是整数。
例如,包含三个元素的集合可能看起来像
X = { ( (1,2),(2,3) ), ( (1,3),(1,2) ), ( (2,3),(1,2) ) }
虽然所有外部元组都是唯一的,但我想构建一个子集,其中包含一组不同的元组,其中两个内部元组的 ORDER 是不相关的(即一组唯一组合)。在上面的示例中,这将减少到;
X = { ( (1,2),(2,3) ), ( (1,3),(1,2) )}
因为
( (1, 2),(2,3) ) and ( (2,3),(1,2) ) )
都是(1, 2)
和(2,3)
的组合。
有明显的 brute-force/for-loop 方法来解决这个问题,但它们感觉不是很 Pythonic。
也许利用 itertools
和 map
?
您可以使用 map
在您的元素上应用 sorted
函数,然后使用集合理解来获取唯一元素:
>>> new={tuple(i) for i in map(sorted,X)}
>>> new
set([('B', 'C'), ('A', 'B'), ('D', 'E')])
但请注意,由于 sorted
将您的元素转换为列表,因此您需要将它们反转为 tuple
,因为列表不可散列。
一种方法是对元组进行排序,然后创建一个新集合。 (A, B) 和 (B, A) 都将被排序到 (A, B),因此只出现一次。
def to_sorted(t):
return tuple(sorted(t))
Xnew = {to_sorted(t) for t in X}
另一种是根本不使用元组 -- 元组是有序的,您不关心顺序。你可以使用集合。 frozensets 是不可变的集合,可以是其他集合的元素:
Xnew = {frozenset(t) for t in X}
我更喜欢这个,但是 1) 如果你的元组包含倍数,它就不起作用,2) 现在你有 frozensets 而不是元组,你的其他代码可能需要更改。
进一步简化(删除地图):
new = {tuple(sorted(n)) for n in X}
TL/DR
给定 X = {(A,B),(B,C),(D,E),(B,A),(C,B)}
(其中 X
是 set
)
如何过滤显示唯一组合(而不是唯一排列)的子元组,使得 X
变为
{(A,B),(B,C),(D,E))}
更长的形式
这里的大多数 combination/permutation 问题有点反问题。
我有一组元组(外元组),其中每个元组有2个元素,都是元组(内元组),每个子元组有两个元素,都是整数。
例如,包含三个元素的集合可能看起来像
X = { ( (1,2),(2,3) ), ( (1,3),(1,2) ), ( (2,3),(1,2) ) }
虽然所有外部元组都是唯一的,但我想构建一个子集,其中包含一组不同的元组,其中两个内部元组的 ORDER 是不相关的(即一组唯一组合)。在上面的示例中,这将减少到;
X = { ( (1,2),(2,3) ), ( (1,3),(1,2) )}
因为
( (1, 2),(2,3) ) and ( (2,3),(1,2) ) )
都是(1, 2)
和(2,3)
的组合。
有明显的 brute-force/for-loop 方法来解决这个问题,但它们感觉不是很 Pythonic。
也许利用 itertools
和 map
?
您可以使用 map
在您的元素上应用 sorted
函数,然后使用集合理解来获取唯一元素:
>>> new={tuple(i) for i in map(sorted,X)}
>>> new
set([('B', 'C'), ('A', 'B'), ('D', 'E')])
但请注意,由于 sorted
将您的元素转换为列表,因此您需要将它们反转为 tuple
,因为列表不可散列。
一种方法是对元组进行排序,然后创建一个新集合。 (A, B) 和 (B, A) 都将被排序到 (A, B),因此只出现一次。
def to_sorted(t):
return tuple(sorted(t))
Xnew = {to_sorted(t) for t in X}
另一种是根本不使用元组 -- 元组是有序的,您不关心顺序。你可以使用集合。 frozensets 是不可变的集合,可以是其他集合的元素:
Xnew = {frozenset(t) for t in X}
我更喜欢这个,但是 1) 如果你的元组包含倍数,它就不起作用,2) 现在你有 frozensets 而不是元组,你的其他代码可能需要更改。
进一步简化(删除地图):
new = {tuple(sorted(n)) for n in X}