【问题标题】:python how to generate combinations from a list of listspython如何从列表列表中生成组合
【发布时间】:2019-05-05 04:28:38
【问题描述】:

我希望你能帮助我,我想从以下列表列表中生成组合(用作 nxn 矩阵):

   A = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]]

但我需要,如果我取第一个列表的第一个数字,然后作为矩阵运算,删除列的其他元素和所选元素的行,然后生成可能的组合

例如,我在第一个列表中选择 1,那么唯一可能生成的组合是:(1,5,9) 和 (1,8,6),因为消除了行和列。

我正在尝试构建一个递归函数来通过删除列和行来实现这一点,问题是我不确定如何使用组合构建列表。

这是我目前为止的:

list = []

def combinations(matrix):
    matrix_rows = len(matrix)
    if matrix_rows == 0:
        # Base case
        return matrix
    else:
        # Recursive case
        # Always select first row
        seq = []
        for index, a in enumerate(matrix[0]):
            E = a
            seq.append(E)
            # Remove i from row of index element a
            new_matrix = remove_row(matrix, 0)
            # Remove j from column index of element a
            new_matrix = remove_column(new_matrix, index)
            # Call again with new matrix
            combinations(new_matrix)
        list.append(seq)
    return list

def remove_row(original_matrix, element_row_index):
    new_matrix = []
    if (len(original_matrix)) >= element_row_index:
        new_matrix = original_matrix[:] 
        new_matrix.remove(original_matrix[element_row_index])
    return new_matrix

def remove_column(matrix, index):
    return [(x[0:index] + x[index + 1:]) for x in matrix]

使用上面的矩阵,我希望有:

A = [[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]]

print("Result: ", combinations(A))

Result: [[1,5,9], [1,6,8], [2,4,9], [2,6,7], [3,4,8], [3,5,7]]

有人可以帮助我吗?或者给我一个更好的方法的建议

添加: 4x4 示例:

A = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]

Results: [1,6,11,16], [1,6,12,15],[1,7,10,16], [1,7,12,14], [1,8,10, 15], [1,8,11, 14], ....

【问题讨论】:

  • 在 Python 中更好的方法是避免递归函数(这在 Python 中相对耗时)并使用 itertools 模块。这可以接受吗?如果是这样,我可以使用这种方法向您展示一个简短的函数。
  • Shure,我尝试过这种方法(使用 itertools.product()),问题是 itertools 生成所有可能的组合,而我只需要满足我上面写的要求的组合,有用 itertools 做到这一点的方法?
  • 如果有 10 个列表,每个列表包含 3 个元素会怎样?
  • 对不起,我忘了添加细节,这仅适用于 nxn 矩阵
  • 你的结果真的很奇怪。我期待 1,8;6 你打印了 1,8,9,即使 8 和 9 在同一行。其他三胞胎没有这个问题

标签: python


【解决方案1】:

我认为这可以简单地完成,根本不需要递归。
基本上,您希望在按顺序遍历列(或分别为行)时,在行(或列)上选择 range(n) 的所有可能排列。
这是一个简单的解决方案:

from itertools import permutations
import numpy as np

n = 3
x = np.arange(n ** 2).reshape((n, n)) + 1  # so as to fit in with your example
perms = permutations(range(n))
combinations = [list(x[range(n), p]) for p in perms]
print(combinations)
>> [[1, 5, 9], [1, 6, 8], [2, 4, 9], [2, 6, 7], [3, 4, 8], [3, 5, 7]]

但是,如果您没有使用与 numpy 兼容的东西,而是使用列表列表,那么对上述内容进行一些小调整也同样有效:

x = [[1, 'A'], [2, 'B']]  # a "small" case so it's easy to follow
n = len(x)
index_list = range(n)
perms = permutations(index_list)
combinations = [[x[i][p[i]] for i in index_list] for p in perms]
print(combinations)
>> [[1, 'B'], ['A', 2]]

以上假设您仍在使用“方形”数据。这意味着每个内部列表的长度与包含它们的外部列表的长度相同。

希望能有所帮助,并能如您所愿。如果不是,请发表评论,我会纠正任何需要的。我会把它变成一个功能给读者;-)
祝你好运!

【讨论】:

  • 这完全不依赖于矩阵内容!我使用范围只是为了获得与您在问题中给出的相同的矩阵。它也适用于 4*4 的情况。或任何n
  • 我认为它可以工作,问题是我的矩阵是随机的,没有必要在一个范围内,例如我可以有 [[9, 2, 7, 8], [6, 4, 3, 7], [5, 8, 1, 8], [7, 6, 9, 4]] ,我从来没有用过 numpy,它对我来说是新的。如果相反,我有一个元组列表,例如 [(1, "A"), (6, "B")] 它可以使用同一个库吗?
  • @ElrosRomeo BTW,我建议在合适的时候使用 numpy。我认为第一个解决方案更好,因为使用 numpy 索引更容易。列表列表 [[9, 2, 7, 8], [6, 4, 3, 7], [5, 8, 1, 8], [7, 6, 9, 4]] 可以很容易制作一个 np.array([[9, 2, 7, 8], [6, 4, 3, 7], [5, 8, 1, 8], [7, 6, 9, 4]] )。
猜你喜欢
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
相关资源
最近更新 更多