【问题标题】:Enumerating three variables in python list comprehension在python列表理解中枚举三个变量
【发布时间】:2016-01-18 11:21:19
【问题描述】:

我正在尝试打印三个变量的列表的所有可能枚举。例如,如果我的输入是:

x = 1
y = 1
z = 1

我希望输出是这样的:

[[0, 0, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0], [1, 1, 0], [1, 0, 1], [0, 1, 1], [1, 1, 1]]

如果 x,y,z 变量中的任何一个大于 1,它将枚举从 0 到变量值的所有整数。例如,如果 x=3,则 0、1、2 或 3 可能位于 3 元素列表的第一个槽中。

现在我正在创建这样的列表理解:

output = [ [x,y,z] for x,y,z in range(x,y,z)]

我认为 range 函数有问题?

【问题讨论】:

  • 你想要完全按照那个顺序输出吗?如果是这样,更复杂的输入的顺序如何?
  • 我不太关心顺序,但希望它可以扩展到非二进制变量值,所以如果 x=2,会有诸如 [2,0,0 之类的列表] [2,0,1], [2,1,0], [2,1,1] 在输出中也是如此。

标签: python list-comprehension


【解决方案1】:

您可以使用itertools 中的product() 函数,如下所示:

from itertools import product

answer = list(list(x) for x in product([0, 1], repeat=3))
print(answer)

输出

[[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]

【讨论】:

  • 实际上,希望变量也可能不是二进制的,所以如果 x=2,y=1,z=1,输出中可能会有类似 [2,1,1] 的列表还有...有没有办法使用 x、y 和 z 变量而不是硬编码 1 和 0 来解决问题?
  • 很乐意提供帮助,但最好将其放在单独的问题中,因为它可能需要稍微不同的方法!
  • 为什么要转换?在将 product 生成器转换为列表之前执行相同的操作,例如[list(x) for x in product(...)]list(map(list, product(...))
【解决方案2】:

作为使用 product 的解决方案的补充,您还可以使用三重列表推导式。

>>> x, y, z = 1, 2, 3
>>> [(a, b, c) for a in range(x+1) for b in range(y+1) for c in range(z+1)]
[(0, 0, 0),
 (0, 0, 1),
 (0, 0, 2),
 (some more),
 (1, 2, 2),
 (1, 2, 3)]

+1 是必需的,因为range 不包括上限。 如果您希望输出为列表列表,您可以使用[[a, b, c] for ...]

但是请注意,这显然只有在您始终拥有三个变量(xyz)时才有效,而product 将适用于任意数量的列表/上限。

【讨论】:

    【解决方案3】:

    您可以在列表理解中使用range() 函数和itertools.product 函数:

    >>> x = 1
    >>> y = 1
    >>> z = 1
    >>> from itertools import product
    >>> list(product(*[range(i+1) for i in [x,y,z]]))
    [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
    

    这种方法也适用于不同的数字:

    >>> x = 2
    >>> y = 2
    >>> z = 2
    >>> 
    >>> list(product(*[range(i+1) for i in [x,y,z]]))
    [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (0, 2, 1), (0, 2, 2), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 2, 0), (2, 2, 1), (2, 2, 2)]
    >>> 
    

    【讨论】:

    • 有没有办法以列表而不是元组的形式获取输出?
    • @WilliamRoss 是的,您可以使用列表推导而不是 list 函数。 [list(item) for item in product(*[range(i+1) for i in [x,y,z]])]
    【解决方案4】:

    如果您需要以列表列表(而不是元组列表)的形式使用它,您可以在 Kasramvd 的答案输出上使用 map,即:

    map(list,list(product(*[range(i+1) for i in [x,y,z]])))
    

    【讨论】:

    • 1) 在 Python 3 中,map 生成生成器,而不是列表,并且 2) 在将 product 返回的生成器传递给 map 之前,无需将其转换为列表。所以这应该是list(map(list, product(...))
    猜你喜欢
    • 2012-06-02
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多