在列表理解中有 'and' 命令
Having 'and' command inside list comprehension
我不明白这个源代码在第 3 行的作用,res = [...];
我试图通过在 python 控制台中使用虚拟变量和与 [=13] 相同的语法格式进行测试来理解=] 它给出了错误;如果使用 res = ['raj' and 'esh'];
进行测试,我总是 return 第二个字符串 '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()]
;此语法行中的路径是文件路径。我能在理解第 3 行方面得到任何帮助吗?
这是一个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)]
是语法 shorthand for
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)
['raj' and 'esh']
是单元素数组,其唯一元素是 'raj'
和 'esh'
的结果; and
如果为假,将求值为第一个操作数,否则为第二个操作数。由于第一个操作数不是假的,你得到 'esh'
.
代码中的行不是一个简单的数组,它是一个理解 - 基本上是编写构造数组的循环的简短方法。理解的一般语法是
[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)
对于 f
的每个元素 o
(大概是文件名的可迭代),如果此条件为真,则结果列表将获得一个由路径串联组成的元素 p
与文件名 o
(/
是一个自然的,如果乍一看令人惊讶,路径的连接运算符。)
代码段中出现的错误命名使问题更加复杂。考虑这个重写:
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
现在这读起来几乎像英语,并且非常清楚它在做什么(唯一不可靠的地方是 path/filename
,几乎任何人都可以通过类比 UNIX 路径猜出那可能是什么)。
我不明白这个源代码在第 3 行的作用,res = [...];
我试图通过在 python 控制台中使用虚拟变量和与 [=13] 相同的语法格式进行测试来理解=] 它给出了错误;如果使用 res = ['raj' and 'esh'];
进行测试,我总是 return 第二个字符串 '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()]
;此语法行中的路径是文件路径。我能在理解第 3 行方面得到任何帮助吗?
这是一个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)]
是语法 shorthand for
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)
['raj' and 'esh']
是单元素数组,其唯一元素是 'raj'
和 'esh'
的结果; and
如果为假,将求值为第一个操作数,否则为第二个操作数。由于第一个操作数不是假的,你得到 'esh'
.
代码中的行不是一个简单的数组,它是一个理解 - 基本上是编写构造数组的循环的简短方法。理解的一般语法是
[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)
对于 f
的每个元素 o
(大概是文件名的可迭代),如果此条件为真,则结果列表将获得一个由路径串联组成的元素 p
与文件名 o
(/
是一个自然的,如果乍一看令人惊讶,路径的连接运算符。)
代码段中出现的错误命名使问题更加复杂。考虑这个重写:
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
现在这读起来几乎像英语,并且非常清楚它在做什么(唯一不可靠的地方是 path/filename
,几乎任何人都可以通过类比 UNIX 路径猜出那可能是什么)。