简体   繁体   English

如何摆脱python中的多个嵌套循环

[英]How to get rid of multiple nested loops in python

This is my code;这是我的代码;

instance_count = 10
for imgs in wire_images:
    for counter in range(0, instance_count, 1):
        for oimgs in images_path:
            applyWireAugmentation(oimgs, imgs, wire_dir, odir, 0, dst_dir, counter, "waug")


def applyWireAugmentation(img, wire_img,wdir, odir, theata,dst_path, counter, index):

    src_im = Image.open(wdir+wire_img).convert("LA")
    dst_im = Image.open(odir+img)
    w,h = dst_im.size
    angle = theata
    size = 200, h

    x = random.randint(0,w)
    y = 0
    im = src_im.convert('RGBA')
    rot = im.rotate( angle, expand=1 ).resize(size)
    dst_im.paste( rot, (x, y), rot )
    dst_im.save(dst_path+"/"+img.replace(".png","")+"-"+index+"-"+str(counter)+".png")

wire_images has all the image files that are in a folder. wire_images包含文件夹中的所有图像文件。 images_path has all the images files in another folder. images_path在另一个文件夹中包含所有图像文件。 I need to take one image from wire_images apply it on oimgs instance_count times (10 in this case).我需要从wire_images获取一张图像wire_images其应用于oimgs instance_count次(在这种情况下为 10)。 Is there any sleek pythonic way to get rid of these loops or to make it faster?是否有任何流畅的 Pythonic 方法来摆脱这些循环或使其更快?

You could generate all the possible combinations before, but I am not sure if it is better:您之前可以生成所有可能的组合,但我不确定它是否更好:

import itertools
comb = itertools.product(wire_images, images_path, range(0,instance_count,1))

for imgs, oimgs, counter in comb:
    applyWireAugmentation(oimgs, imgs,wire_dir,odir, 0, dst_dir, counter,  "waug")

itertools.product can be helpful here. itertools.product在这里很有帮助。

It can transform nested for loops to tuples which you can then use in your final statement.它可以将嵌套的 for 循环转换为元组,然后您可以在最终语句中使用这些元组。

You code will be like this:你的代码会是这样的:

from itertools import product   

for imgs, counter, oimgs in product(wire_images, range(0,instance_count,1), images_path):

    applyWireAugmentation(oimgs, imgs, wire_dir, odir, 0, dst_dir, counter, "waug")

Keep in mind that this for loop will not execute if any of the lists(iterators) are empty and it is a bit slower than nested for loop so you have to sacrifice performance a little bit in favor of readability.请记住,如果任何列表(迭代器)为空,则此 for 循环将不会执行,并且它比嵌套 for 循环慢一点,因此您必须牺牲一点性能来提高可读性。

Have a look at this Stackoverflow discussion for more info查看此 Stackoverflow 讨论以获取更多信息

As others suggested, one of the best possible way to achieve this is to use a generator which reduces the memory overhead drastically since there is no list to hold in-memory.正如其他人建议的那样,实现这一目标的最佳方法之一是使用生成器,由于没有可保存在内存中的列表,因此可大大减少内存开销。

from itertools import product

wire_images = list1...  # if possible, try to get them in iterator format as well
images_path = list2...   # if possible, try to get them in iterator format as well
instance_count = 10

for imgs, oimgs, counter in product(wire_images, images_path, range(instance_count)):
    applyWireAugmentation(oimgs, imgs, wire_dir, odir, 0, dst_dir, counter, "waug")

The above approach has trade off of time over space and readability.上述方法在时间与空间和可读性之间进行权衡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM