列表理解中包含“和”命令

时间:2018-11-25 23:17:12

标签: python pathlib

我不了解此源代码在第3行上所做的工作,res = [...];是我尝试通过在Python控制台中使用伪变量并以与res = ['raj' / 'esh'];相同的语法格式进行测试来理解的,它给出了错误;如果用res = ['raj' and 'esh'];测试,我总是返回第二个字符串'esh',所以我很困惑为什么在行中使用'and'。 p / o语法也使我感到困惑。

def _get_files(parent, p, f, extensions):
    p = Path(p)  #.relative_to(parent)
    res = [p/o for o in f if not o.startswith('.')
           and (extensions is None or f'.{o.split(".")[-1].lower()}' in extensions)]
    return res

解析的参数p是文件路径(字符串),解析的参数f是f = [o.name for o in os.scandir(path) if o.is_file()];该语法行中的path是文件路径。在理解第3行时,我可以获得任何帮助吗?

2 个答案:

答案 0 :(得分:1)

这是list comprehension

res = [p/o for o in f if not o.startswith('.')
       and (extensions is None or f'.{o.split(".")[-1].lower()}' in extensions)]

是语法的简写

res = []
for o in f:
    if not o.startswith('.') and (extensions is None or f'.{o.split(".")[-1].lower()}' in extensions):
        res.append(p/o)

答案 1 :(得分:1)

['raj' and 'esh']是一个单元素数组,其唯一元素是'raj''esh'的结果; and将得出第一个操作数(如果为假),否则为第二个操作数。由于第一个操作数不是伪造的,所以得到'esh'

代码中的行不是简单的数组,而是 comprehension -基本上是编写构造数组的循环的一种简短方法。理解的一般语法是

[x for y in z if p]

其中y将遍历可迭代z的所有元素,检查p是否为真,如果是,则将x添加到结果中。您的情况(p)是

not o.startswith('.')
and
(extensions is None or f'.{o.split(".")[-1].lower()}' in extensions)

对于o中的每个元素f(可能是文件名的迭代),如果此条件为true,则结果列表将获得一个元素,该元素由路径{{1}的串联组成}和文件名po是自然的,如果乍看之下很自然,是路径的串联运算符。)

该片段中出现的不良命名使问题更加复杂。考虑以下重写:

/

现在,它读起来几乎像英语,并且非常清楚它在做什么(唯一的狡猾之处是def _hidden(filename): return filename.startswith('.') def _extension(filename): return '.' + filename.split(".")[-1].lower() def _extension_ok(filename, allowed_extensions=None): return allowed_extensions is None or _extension(filename) in allowed_extensions def _get_files(parent, path, filenames, allowed_extensions=None): path = Path(path) good_paths = [path/filename for filename in filenames if not _hidden(filename) and _extension_ok(filename, allowed_extensions)] return good_paths ,几乎每个人都可以通过类比UNIX路径来猜测那是什么)。