How to reuse an expression in a comprehension expression?
Yes! Python 3.8 introduces the "Assignment operator" :=
, which allows you to define a variable within the local scope of a single expression (e.g. a comprehension). In your example, you would do this:
result = {(p := next(k for k in ('path', 'subdir') if k in e)): some_func(p)
for e in bad_structure}
Disclaimer: this will not work in any version of python before 3.8.
You can use an intermediate comprehension to bind to a name:
result = {
p: some_func(p)
# bind intermediate result to p
for p in ( # nested comprehension to produce intermediate result
next(k for k in ('path', 'subdir') if k in e)
for e in bad_structure
)
}
Instead of mapping directly to two separate expressions, it first maps to a common expression which then is mapped to two separate expressions.
You can pass along and rename an arbitrary number of values. Create a tuple in the inner comprehension, and unpack it to multiple names in the outer comprehension.
result = {
p: some_func(e, p)
for e, p in (
(e, next(iter(e)))
for e in bad_structure
)
}