代码之家  ›  专栏  ›  技术社区  ›  Jonathan

如何逐步将一个列表变形为另一个列表(两个列表的笛卡尔积)?

  •  0
  • Jonathan  · 技术社区  · 6 年前

    假设我有两个列表,

    one = ['a1', 'b1', 'c1']
    two = ['a2', 'b2', 'c2']
    

    我希望生成这些项的所有可能组合的集合,而不更改它们在各自列表中的位置。因此,对于上面的例子,应该是:

    ['a1', 'b1', 'c1']
    ['a1', 'b1', 'c2']
    ['a1', 'b2', 'c2']
    ['a2', 'b1', 'c1']
    ['a2', 'b2', 'c1']
    ['a2', 'b2', 'c2']
    

    我在看 itertools 希望找到符合这个描述的东西,但我还没有找到。

    1 回复  |  直到 6 年前
        1
  •  5
  •   Rory Daulton    6 年前

    你要找的功能是 product 但你需要先设置它。问题是,您的值是“侧向的”——您希望将第一个位置的所有可能值放在一起,然后将第二个位置的所有可能值放在一起,等等。您可以使用 *zip() 演习。

    from itertools import product
    list(product(*zip(one, two)))
    

    结果是

    [('a1', 'b1', 'c1'),
     ('a1', 'b1', 'c2'),
     ('a1', 'b2', 'c1'),
     ('a1', 'b2', 'c2'),
     ('a2', 'b1', 'c1'),
     ('a2', 'b1', 'c2'),
     ('a2', 'b2', 'c1'),
     ('a2', 'b2', 'c2')]
    

    如果您真的想要列表而不是元组,请使用

    [list(v) for v in product(*zip(one, two))]
    

    这给了你

    [['a1', 'b1', 'c1'],
     ['a1', 'b1', 'c2'],
     ['a1', 'b2', 'c1'],
     ['a1', 'b2', 'c2'],
     ['a2', 'b1', 'c1'],
     ['a2', 'b1', 'c2'],
     ['a2', 'b2', 'c1'],
     ['a2', 'b2', 'c2']]
    

    请注意,这些并不完全是您列出的所需输出,因为您遗漏了一些可能性。