将范围向量转换为 Python 中的集合组合
Converting a vector of ranges into combination of sets in Python
在 Python 中,我有一个这样的范围列表:
A = [range(0,2),range(0,4),range(0,3),range(0,3)]
首先,我必须将所有这些范围转换为集合。我可以创建一个空集并将结果列表添加到其中。我会:
B = [[0, 1], [0, 1, 2, 3], [0, 1, 2], [0, 1, 2]]
但在那之后,我必须在列表之间创建所有可能的元素组合。具有最低值的集合将是 [0, 0, 0, 0],最高值将是:[1, 3, 2, 2]。这将是 2x4x3x3 = 72 组的组合。我怎样才能达到这个结果,从范围列表 (A) 开始?
要获得笛卡尔积,请执行以下操作:
A = []
for i in range(2):
for j in range(4):
for k in range(3):
for n in range(3):
combo = [i,j,k,n]
A.append(combo)
您可以使用内置的 itertools
模块获取 A
中所有 range
对象的笛卡尔积,并完全跳过 B
:
import itertools
A = [range(2), range(4), range(3), range(3)]
list(itertools.product(*A))
输出(为了便于阅读跳过了一些项目):
[(0, 0, 0, 0),
(0, 0, 0, 1),
(0, 0, 0, 2),
(0, 0, 1, 0),
(0, 0, 1, 1),
.
.
.
(1, 3, 2, 2)]
验证长度:
>>> len(list(itertools.product(*A)))
72
请注意 itertools.product()
会产生 tuple
个对象。如果出于某种原因你更喜欢这些列表,你可以使用理解:
[[*p] for p in itertools.product(*A)]
正如@don'ttalkjustcode 指出的那样,另一种方法是您可以避免完全创建 A
并通过 map()
函数直接跳到笛卡尔积:
list(itertools.product(*map(range, (2, 4, 3, 3))))
但是,这假设您的所有范围都从 0 开始。
您可以通过使用 lambda
来概括此映射技术,它将从元组列表创建范围对象:
>>> list(map(lambda t: range(*t), ((6, -3, -1), (0, 3), (5,), (10, 1, -2))))
[range(6, -3, -1), range(0, 3), range(0, 5), range(10, 1, -2)]
在 Python 中,我有一个这样的范围列表:
A = [range(0,2),range(0,4),range(0,3),range(0,3)]
首先,我必须将所有这些范围转换为集合。我可以创建一个空集并将结果列表添加到其中。我会:
B = [[0, 1], [0, 1, 2, 3], [0, 1, 2], [0, 1, 2]]
但在那之后,我必须在列表之间创建所有可能的元素组合。具有最低值的集合将是 [0, 0, 0, 0],最高值将是:[1, 3, 2, 2]。这将是 2x4x3x3 = 72 组的组合。我怎样才能达到这个结果,从范围列表 (A) 开始?
要获得笛卡尔积,请执行以下操作:
A = []
for i in range(2):
for j in range(4):
for k in range(3):
for n in range(3):
combo = [i,j,k,n]
A.append(combo)
您可以使用内置的 itertools
模块获取 A
中所有 range
对象的笛卡尔积,并完全跳过 B
:
import itertools
A = [range(2), range(4), range(3), range(3)]
list(itertools.product(*A))
输出(为了便于阅读跳过了一些项目):
[(0, 0, 0, 0),
(0, 0, 0, 1),
(0, 0, 0, 2),
(0, 0, 1, 0),
(0, 0, 1, 1),
.
.
.
(1, 3, 2, 2)]
验证长度:
>>> len(list(itertools.product(*A)))
72
请注意 itertools.product()
会产生 tuple
个对象。如果出于某种原因你更喜欢这些列表,你可以使用理解:
[[*p] for p in itertools.product(*A)]
正如@don'ttalkjustcode 指出的那样,另一种方法是您可以避免完全创建 A
并通过 map()
函数直接跳到笛卡尔积:
list(itertools.product(*map(range, (2, 4, 3, 3))))
但是,这假设您的所有范围都从 0 开始。
您可以通过使用 lambda
来概括此映射技术,它将从元组列表创建范围对象:
>>> list(map(lambda t: range(*t), ((6, -3, -1), (0, 3), (5,), (10, 1, -2))))
[range(6, -3, -1), range(0, 3), range(0, 5), range(10, 1, -2)]