如何使用列表推导来简化多个列表和字符串的排序和添加?

时间:2018-04-28 21:22:24

标签: python string sorting directory list-comprehension

下面的循环将获取目录和/或图像列表,它将返回图像列表,包括提供的目录中的图像。对于给出的每个目录,它会在将该图像添加到列表之前验证每个文件确实是有效图像。

import os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-style_image", help="List of images and/or directories")
params = parser.parse_args()

style_image_input = params.style_image.split(',')
valid_ext, style_input_sorted = [".jpg",".png"], None
for image in style_image_input:
    if os.path.isdir(image):
        for file in os.listdir(image):
            print(file)
            ext = os.path.splitext(file)[1]
            if ext.lower() not in valid_ext:
                continue
            if style_input_sorted == None:
                style_input_sorted = file
            else: 
                style_input_sorted += "," + file
    else:
        if style_input_sorted == None:
            style_input_sorted = image
        else: 
            style_input_sorted += "," + image 
style_image_list = style_input_sorted.split(',')
print(style_image_list)

如何使用列表推导来简化此循环?

1 个答案:

答案 0 :(得分:3)

忘记“我怎样才能把它变成列表理解”。从“我如何简化这一点”开始。如果最后你得到一个带有一个或两个子句和一个简单表达式的循环,那么你可以考虑将其转换为列表理解,但这是最后一步,而不是起始目标。

您的大多数重复都与您构建style_input_sorted的方式有关:

  • 将其设为None
  • 每次获得值时,如果是None,请将其设置为值
  • 否则,请添加逗号,然后添加值。

而不是从None开始,可以""开头,然后执行此操作:

if style_input_sorted:
    style_input_sorted += ","
style_input_sorted += file

但是,更简单地说:你所做的是同样的事情str.join已经知道怎么做了。如果你可以建立一个列表的字符串,然后只列出最后列出的join,那就简单多了:

style_input_sorted = []
if …
    for …
        style_input_sorted.append(file)
else …
    style_input_sorted.append(file)
style_input_sorted = ",".join(style_input_sorted)

但看起来你用style_input_sorted做的唯一事情就是把它拆分成一个列表。那么为什么甚至加入一个字符串只是为了拆分呢?

style_input_list = []
if …
    for …
        style_input_list.append(file)
else …
    style_input_list.append(file)

您可以进行其他一些简化,但这是最大的简化,它将为下一个简化打开大门。例如,既然你只做了一件微不足道的事情而不是四行代码来进行有效的扩展,你可以摆脱continue

if os.path.isdir(image):
    for file in os.listdir(image):
        ext = os.path.splitext(file)[1]
        if ext.lower() in valid_ext:
            style_input_list.append(file)
else:
    style_input_list.append(file)

现在我们有一篇文章可以转化为列表理解 - 尽管我使用了生成器表达式:

if os.path.isdir(image):
    images = (file for file in os.listdir(image)
              if os.path.splitext(file)[1].lower() in valid_ext)
    style_input_list.extend(images)
else:
    style_input_list.append(image)

但是将整个事情变成一个列表理解将是非常难看的。您可以使用三元if将其转换为表达式,并在最后展平整个事物,但如果您有五行代码,则不属于理解范围。 (当然你可以把这五行放到一个函数中,然后将对该函数的调用包装成一个理解,这可能是值得做的。)