Short writing the iterate loop in one line

Viewed 56

can you please tell me how to shorten the writing of the iterating loop in one line without writing join(path, name) twice? Maybe it can be implemented through lambda? Does my example calculate the path twice? Thanks

import os
from os.path import exists, join

path = r"C:\Test_folder\\"
name_list = ["image01.png", "image02.png", "image03.png"]
result = [join(path, name) for name in name_list if exists(join(path, name))]
2 Answers

Yes, your code does evaluate join(path, name) twice per iteration.

If you insist on using a list comprehension and using Python >= 3.8 you can use an assignment expression:

result = [p for name in name_list if exists(p := join(path, name))]

This evaluates join(path, name) once per iteration, assigns its return value to p and evaluates exists(p), then if it's true it is being added to the resulting list.

This is roughly equivalent to

result = []
for name in name_list:
    p = join(path, name)
    if exists(p):
        result.append(p)
result = [abs_path for abs_path in [join(path, name) for name in name_list] if exists(abs_path)]

It can be made as two lines:

abs_pathes = [join(path, name) for name in name_list]
result = [abs_path for abs_path in abs_pathes if exists(abs_path)]

So, it is not nested.

Related