I do not understand what this source code does on line 3, res = [...];
I tried to understand by testing out in python console with dummy variables and in the same syntax format like res = ['raj' / 'esh'];
it gives error; if tested with res = ['raj' and 'esh'];
I always return the second string 'esh'
, so I'm confused why use 'and' in the line. The syntax p/o also confuses me.
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
Argument p
parsed is file path (string), argument f parsed is f = [o.name for o in os.scandir(path) if o.is_file()]
; where path in this syntax line is file path. Could I get any help in understanding line 3?
['raj' and 'esh']
is a one-element array, whose sole element is the result of 'raj'
and 'esh'
; and
will evaluate to the first operand if falsy, and second operand otherwise. Since the first operand is not falsy, you get 'esh'
.
The line in the code is not a simple array, it is a comprehension - basically a short way to write a loop that constructs an array. The general syntax of a comprehension is
[x for y in z if p]
where y
will loop over all elements of the iterable z
, check if p
is true, and if it is, add x
to the result. In your case, the condition (p
) is
not o.startswith('.')
and
(extensions is None or f'.{o.split(".")[-1].lower()}' in extensions)
For each element o
of f
(presumably an iterable of filenames), if this criterion is true, the result list will gain an element which consists of the concatenation of the path p
with the filename o
(/
being a natural, if surprising at first sight, concatenation operator for paths.)
The problem is compounded by bad naming exhibited in the snippet. Consider this rewrite:
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
Now this reads almost like English, and is very clear about what it's doing (the only dodgy bit being path/filename
, and almost anyone could guess what that might be just by analogy to UNIX paths).