置换5(或6)个列表

时间:2014-01-30 20:48:30

标签: python algorithm permutation

哪种是最优雅和Pythonic的方式来置换5或6个列表中的元素?

我有一堆像下面这样的列表,其中每个元素都会触发一个AJAX调用。当列表3中的元素将被迭代时,它们可能会拉出另一个我需要置换的列表,并且我需要使所有排列成为可能。

列表理解不在讨论中,因为我需要在每次调用之间进行一些操作。

我知道itertools.permutations,但我正在寻找能让我在每一步都有更多控制权的东西。

list1 =['e1', 'e2', 'e3']
list2 = ['e1', 'e2', ... , 'e13']
list3 = [up to 15 elements]
variable_list = ['e1', 'e2']
list4 = ['e1', 'e2']
list5 = ['e1', 'e2', ... , 'e16']

这是我想要处理的清单:

values = [[{'0': '25'},
      {'0': '50'},
      {'0': '75'},
      {'0': '100'},
      {'0': '250'},
      {'0': '500'},
      {'0': '750'},
      {'0': '1000'},
      {'0': '2500'},],
     [{'1': 'abc|xyz'}],
     [{'2': 'Color|purple'}, {'2': 'Color|black'}],
     [{'3': 'yes|no'},
      {'3': 'no|yes'}],
     [{'4': 'Round|no'}, {'4': 'Round|yes'}],
     [{'5': 'time|4-5'}],
     [{'Base': 'gl'}],
     [{'Type': '123'}]]

值元素的数量可能会改变,而不是所有时间都有这个长度 - 8个元素,所以我也需要处理它。

我需要返回一个包含所有可能组合的列表: 以下是我需要的列表元素的示例:

[{'0': '25'}, {'1': 'abc|xyz'}, {'2': 'Color|purple'}, {'3': 'yes|no'}, {'4': 'Round|no'}, {'5': 'time|4-5'}, {'Base': 'gl'}, {'Type': '123'}]

结果列表中每个元素的长度必须与输入列表中的长度相等(在我的情况下为值)。

我试过了itertools.permutation但是给了我比我需要的更多的结果。另外,我尝试了@markcial建议,但如果我不知道输入列表的长度,它就不起作用。

2 个答案:

答案 0 :(得分:1)

你谈论排列和组合,但在我看来你真的想要由itertools.product生成的笛卡尔积。例如:

>>> from itertools import product
>>> values = [[{'0': '25'}, {'0': '50'}, {'0': '75'}, {'0': '100'}, {'0': '250'}, {'0': '500'}, {'0': '750'}, {'0': '1000'}, {'0': '2500'}], [{'1': 'abc|xyz'}], [{'2': 'Color|purple'}, {'2': 'Color|black'}], [{'3': 'yes|no'}, {'3': 'no|yes'}], [{'4': 'Round|no'}, {'4': 'Round|yes'}], [{'5': 'time|4-5'}], [{'Base': 'gl'}], [{'Type': '123'}]]
>>> every_choice = list(product(*values))
>>> len(every_choice)
72

every_choice的每个元素都是一个元组,每个列表中都有一个元素:

>>> every_choice[0]
({'0': '25'}, {'1': 'abc|xyz'}, {'2': 'Color|purple'}, {'3': 'yes|no'}, {'4': 'Round|no'}, {'5': 'time|4-5'}, {'Base': 'gl'}, {'Type': '123'})
>>> every_choice[30]
({'0': '100'}, {'1': 'abc|xyz'}, {'2': 'Color|black'}, {'3': 'no|yes'}, {'4': 'Round|no'}, {'5': 'time|4-5'}, {'Base': 'gl'}, {'Type': '123'})
>>> every_choice[-1]
({'0': '2500'}, {'1': 'abc|xyz'}, {'2': 'Color|black'}, {'3': 'no|yes'}, {'4': 'Round|yes'}, {'5': 'time|4-5'}, {'Base': 'gl'}, {'Type': '123'})

答案 1 :(得分:0)

list comprehension也可以调用函数。您可以像这样

为列表推导步骤创建一个函数
def do(*args):
    print args
    return args

然后使用list comprehension调用当前步骤的函数:

list1 =['e1', 'e2', 'e3']
list2 = ['e1', 'e2', 'e13']
[do(a,b) for a in list1 for b in list2]

后续循环可以添加更复杂的例程,但主要思想是你可以控制列表理解循环