【问题标题】:Permutations of mapping two nested lists映射两个嵌套列表的排列
【发布时间】:2021-03-27 16:49:17
【问题描述】:

我有两个嵌套列表,它们按列表长度的升序排列。例如:

listA= [[1],[2],[3,4],[5,6]]
listB= [[A],[B],[C,D],[E,F]]

我想获取将 listA 中的列表映射到相同索引的 listB 中的列表的所有排列,并以字典列表或元组列表的形式进行处理。我想要的输出的一个例子是:

dict1 = { 1->A,2->B,3->C,4->D,5->E,6->F}
dict2 = { 1->A,2->B,3->D,4->C,5->E,6->F}
dict3 = { 1->A,2->B,3->C,4->D,5->F,6->E}
dict4 = { 1->A,2->B,3->D,4->C,5->F,6->E}

我尝试过使用 itertools 产品和排列,但没有得到想要的结果。我目前的方法是获取每个列表对的映射排列,然后迭代地创建每个可能的字典,但这不是我满意的解决方案。如果有人能提出解决这个问题的好方法,我将不胜感激!

【问题讨论】:

    标签: python


    【解决方案1】:

    我想这就是你想要的:

    import itertools as it
    listA= [[1],[2],[3,4],[5,6]]
    listB= [['A'],['B'],['C','D'],['E','F']]
    
    result = []
    for i in range(len(listA)):
        result.append(list(it.product(listA[i], listB[i])))
    
    print(result)
    #[[(1, 'A')], [(2, 'B')], [(3, 'C'), (3, 'D'), (4, 'C'), (4, 'D')], [(5, 'E'), (5, 'F'), (6, 'E'), (6, 'F')]]
    

    或者,如果您想要一维列表中的所有元组:

    result = []
    for i in range(len(listA)):
        result.extend(list(it.product(listA[i], listB[i])))
    
    #[(1, 'A'), (2, 'B'), (3, 'C'), (3, 'D'), (4, 'C'), (4, 'D'), (5, 'E'), (5, 'F'), (6, 'E'), (6, 'F')]
    

    【讨论】:

    • @ThierryLathuille OP 说元组列表会很好。我同意预期的输出存在一些歧义。
    • 元组而不是字典,但在这种情况下,预期的输出应该是 4 个结构,每个结构都包含一种可能的组合;
    • @ThierryLathuille 是的,我想要每种可能的组合。组合的数量是每个列表长度的阶乘的乘积。因此,对于我的示例,它将是 2!x2!。
    【解决方案2】:

    您可以使用递归生成器函数:

    from itertools import permutations as perm
    def get_combos(d, c = []):
      if not d:
         yield c
      else:
         a, b = d[0]
         for i in perm(a):
            yield from get_combos(d[1:], c+[*zip(i, b)])
    
    listA= [[1],[2],[3,4],[5,6]]
    listB= [['A'],['B'],['C','D'],['E','F']]
    r = [dict(i) for i in get_combos(list(zip(listA, listB)))]
    

    输出:

    [{1: 'A', 2: 'B', 3: 'C', 4: 'D', 5: 'E', 6: 'F'}, 
     {1: 'A', 2: 'B', 3: 'C', 4: 'D', 6: 'E', 5: 'F'}, 
     {1: 'A', 2: 'B', 4: 'C', 3: 'D', 5: 'E', 6: 'F'}, 
     {1: 'A', 2: 'B', 4: 'C', 3: 'D', 6: 'E', 5: 'F'}]
    

    【讨论】:

    • 我建议生成元组而不是列表,特别是如果您要重用列表(在这种情况下,它是一个可变的默认参数,因此它将在多个调用中重用)。问题是调用者是否改变了生成器产生的列表。您可以将c=() 写为默认值,将c + tuple(zip(i, b)) 改为。
    • 我将尝试使用元组建议,因为我对这个函数的目标将适用于字典或元组。谢谢你们的帮助!
    猜你喜欢
    • 1970-01-01
    • 2017-05-25
    • 2020-04-02
    • 2018-04-21
    • 1970-01-01
    • 2019-11-15
    • 2020-04-06
    • 2016-02-12
    • 1970-01-01
    相关资源
    最近更新 更多