Skip to main content
 首页 » 编程设计

Python,压扁一个丑陋的嵌套for循环

2025年05月04日20pengyingh

我想把几个数据文件通过两个模块来处理它们,使用每个模块的几个参数的几个设置的每个组合。执行此操作的明显方法是使用嵌套 for 循环,但是当您达到 7+ 嵌套 for 循环时,没有。我想让这个比那个更优雅。

我已经读过几个非常相似的问题,但是 this one表明我可能想使用 itertools,它只遍历数字序列,而我想遍历作为值包含在字典中的字符串列表; this other one揭示了我想要的被称为笛卡尔积,但不是如何从字典值中得到它;同时 this one结合笛卡尔积中的列表字典,我希望输出是列表列表,如上一个链接问题,而不是字典列表。

在:

video = ["It's Friday.mp4",'Hot Koolaid.mov','The Water Buffalo Song.mp4'] 
CC = {'size':['6','10','14'],'font':['Courier New'],'color':['black','white'],'language':['English']} 
Noise = {'CRT':['speckles','rising stripes','no signal'],'sound':['white','crackle']} 

输出:

[['It's Friday.mp4','6','Courier New','black','English','speckles','white'],  
 ['Hot Koolaid.mov','6','Courier New','black','English','speckles','white'] 
 ... 
 ['The Water Buffalo Song.mp4','14','Courier New','white','English','no signal','crackle']] 

我很确定我想使用 itertools,而且我想做的是列表的笛卡尔积。我认为目前最难的事情是从字典中提取这些列表,并将它们的元素组合成列表。

________编辑:____________

在检查我随后接受的答案的过程中,我发现所有参数都在列表中很重要(为了我的目的),即使只考虑一个值也是如此;没有方括号的字符串将一次迭代一个字符。

丑陋的嵌套 for 循环看起来像:

for vid in video: 
    for siz in CC['size']: 
        for fon in CC['font']: 
            for col in CC['color']: 
                for lan in CC['language']: 
                    for crt in Noise['CRT']: 
                        for sou in Noise['sound']: 
                            some_function(vid,siz,fon,col,lan,crt,sou) 

请您参考如下方法:

字典足够小,将七个参数硬编码到 itertools.product 是最简单的:一个“独立”列表,来自 CC 的四个列表,以及来自 Noise 的两个列表。

from itertools import product 
result = list(product( 
                  video, 
                  CC['size'], 
                  CC['font'], 
                  CC['color'], 
                  CC['language'], 
                  Noise['CRT'], 
                  Noise['sound'] 
         )) 

您可以使用 operator.itemgetter 稍微简化一下,这样可以消除对两个词典的重复提及。

from operator import itemgetter 
result = list(product( 
                  video, 
                  *itemgetter('size', 'font', 'color', 'language')(CC), 
                  *itemgetter('CRT', 'sound')(Noise) 
         )) 

如果您确定字典值的生成顺序,您可以进一步缩短它:

result = list(product(video, *CC.values(), *Noise.values()))