如何从元组列表生成组合

2024-10-03 23:27:42 发布

您现在位置:Python中文网/ 问答频道 /正文

  • 如何从tupleslist生成组合,其中每个元组在索引0处是string,在索引1处是list
  • 鉴于{}中的{}如下所示:
params = ['sn', 'tp', 'v1', 'temp', 'slew']

list_tuple = [('Serial Number', [12345]),
              ('Test Points', ['TestpointA', 'TestpointC']),
              ('Voltage_1', [3.0, 3.3, 3.6, 0.0]),
              ('Temperature Setpoint', [0, 60]),
              ('Slew_1', [200, 400, 800, 1600, 3200, 6400])]

# working nested loop
def what_i_want(test_tuple, params):
    for sn in test_tuple[0][1]:
            for tp in test_tuple[1][1]:
                for v in test_tuple[2][1]:
                    for temp in test_tuple[3][1]:
                        for slew in test_tuple[4][1]:
                            print(f'{params[0]}: ', sn)
                            print(f'{params[1]}: ', tp)
                            print(f'{params[2]}: ', v)
                            print(f'{params[3]}: ', temp)
                            print(f'{params[4]}: ', slew)
                            print('\n')

what_i_want(list_tuple, params)

产生所需的输出:

sn:  12345
tp:  TestpointA
v1:  3.0
temp:  0
slew:  200

sn:  12345
tp:  TestpointA
v1:  3.0
temp:  0
slew:  400
...
...

params的长度对应于list_tuple内的tuples的数量,并且该长度可以变化,这意味着嵌套循环的变化。tuple中每个list的长度也可以不同(即list'Serial Number'的长度可以是3或4个元素,而不是1个)

如果没有嵌套循环,如何生成所需的输出

我尝试使用递归来解包list_tuple并通过索引调用params,但没有成功

# not working recursive function
def not_working(list_tuple):
    for i in list_tuple:
        if isinstance(i, tuple):
            print(i[0])
            not_working(i[1])
        else:
            print(i)
            print('\n')


not_working(list_tuple)

[out]:

Serial Number
12345


Test Points
TestpointA


TestpointC


Voltage_1
3.0


3.3


3.6


0.0


Temperature Setpoint
0


60


Slew_1
200


400


800


1600


3200


6400

Tags: intestfornotparamstemplistworking
1条回答
网友
1楼 · 发布于 2024-10-03 23:27:42

您可以使用itertools.product

import itertools
data = [('Serial Number', [12345]), ('Test Points', ['TestpointA', 'TestpointC']), ('Voltage_1', [3.0, 3.3, 3.6, 0.0]), ('Temperature Setpoint', [0, 60]), ('Slew_1', [200, 400, 800, 1600, 3200, 6400])]
params = ['sn', 'tp', 'v1', 'temp', 'slew']
for i in itertools.product(*[b for _, b in data]):
  print('\n'.join(f'{a}:{b}' for a, b in zip(params, i)))
  print('-'*20)

输出(前三个结果):

sn:12345
tp:TestpointA
v1:3.0
temp:0
slew:200
          
sn:12345
tp:TestpointA
v1:3.0
temp:0
slew:400
          
sn:12345
tp:TestpointA
v1:3.0
temp:0
slew:800
          
...

虽然itertools.product可能是这个问题最干净的解决方案,但是可以使用一个带有生成器的简单递归函数

ddata之间有什么区别<在递归函数中,d在每次迭代时通过列表切片(d[i+1:])进行变异。由于d的长度减少,并且len(d)在函数的范围内查找对象d的长度,它将不会查找存储原始数据的列表的长度,而是查找传递给combination的当前值的长度,该值在每次调用时都会减少

def combination(d, current = []):
   if len(current) == len(data):
     yield current
   else:
     for i, a in enumerate(d):
       for c in a: 
         yield from combination(d[i+1:], current = current+[c])
       

for i in combination([b for _, b in data]):
  print('\n'.join(f'{a}:{b}' for a, b in zip(params, i)))
  print('-'*20)

输出(前三个结果):

sn:12345
tp:TestpointA
v1:3.0
temp:0
slew:200
          
sn:12345
tp:TestpointA
v1:3.0
temp:0
slew:400
          
sn:12345
tp:TestpointA
v1:3.0
temp:0
slew:800
          

相关问题 更多 >