This will read much more easily as a regular for loop:
new_list = []
for i in old_list:
if not re.findall(r'find_pattern', i, re.M):
new_list.append(re.sub(r'replace_a', 'with_b', i))
elif foo == re.match("pattern", foo):
new_list.append(re.sub(r'replace_c', r'with_d', i))
# else:
# i
Your problem is that a conditional expression must always take an else
clause, because it has to have some value whether or not the condition is true. With an if
statement, however, you can omit the else
. The above, for instance, has the ability to make new_list
shorter than old_list
, as not every i
needs to result in a call to new_list.append
. Uncommenting the else
results in the same result as jpp's answer.
If you insist on using a list comprehension, then you can format it to make it more readable. Consider
new_list = [re.sub(r'replace_pattern_a', 'with_pattern_b', i)
if not re.findall(r'find_pattern', i, re.M) else
re.sub(r'replace_pattern_c', r'with_pattern_d', i)
if foo == re.match("pattern", foo) else
i
for i in old_list]
although the conditional expression really isn't designed for such nesting. This visually separates the expressions that could be added to the new list from the conditions used to make the decision, but I'm not a big fan. There are other ways to format that make different trade-offs, but IMO the regular for
loop is superior.
As jpp mentions, another way to refactor is to define a generator function:
def foo(old_list):
for i in old_list:
if not re.findall(r'find_pattern', i, re.M):
yield re.sub(r'replace_a', 'with_b', i))
elif foo == re.match("pattern", foo):
yield re.sub(r'replace_c', r'with_d', i))
else:
yield i
new_list = list(foo())
which would have its pros and cons as well. (I think enumerating those is probably beyond the scope of this answer, but it does fall somewhere between the two extremes of a single list comprehension and an explicit for
loop. It also comes closest to the construct I miss from my Perl days, the do
statement, which is something like a lambda
that doesn't take any arguments, but can contain arbitrary statements.)