【问题标题】:Converting a vector of ranges into combination of sets in Python将范围向量转换为 Python 中的集合组合
【发布时间】:2021-09-24 22:54:12
【问题描述】:

在 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) 开始,我怎样才能达到这个结果?

【问题讨论】:

  • python 中的集合就像 {0,1} 使用大括号。简单的括号是列表

标签: python set range combinations


【解决方案1】:

您可以使用内置的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)]

【讨论】:

  • 甚至可以做到product(*map(range, [2, 4, 3, 3]))
  • 既然你在使用itertools,你could also use starmap
  • 谢谢!使用内置的 itertools 确实有效。
  • @ChrSld 很高兴我能提供帮助。如果您满意,请继续接受答案。这样您的问题就可以从未回答的队列中删除。
【解决方案2】:

要获得笛卡尔积,请执行以下操作:

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)

【讨论】:

  • 请注意,您使用的术语不正确。您的代码不会产生组合,它会产生笛卡尔积。
  • 我认为他想要所有范围内的所有可能组合。我验证了我的脚本,它产生了 len(A) = 72。
  • 不,他们描述的是笛卡尔积,您的代码也会产生它。我是说你只是用错误的名字称呼它。您的代码是正确的,但它不是组合,而是笛卡尔积。
  • @ddejohn 所以如果我有四件衬衫和三件裤子,我不能说我有 12 种组合可以穿吗?我必须说衬衫和裤子的笛卡尔积的基数是 12?比较可笑。完全没问题。
  • 当“组合”在组合学的上下文中具有非常具体的含义时,是的,我认为让人们知道他们何时使用不正确的术语是合理的,因为它会引起混淆。在日常生活中随意使用“组合”这个词是可以的,但在您谈论计数时就不行了。
猜你喜欢
  • 2014-04-09
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
相关资源
最近更新 更多