3 ms·
Based on Haskell do-notation, Firefox's unfortunately withdrawn array comprehensions, and C# LINQ, I've been thinking about this: [for b in c let d =
by kragen 1y ago
Based on Haskell do-notation, Firefox's unfortunately withdrawn array comprehensions, and C# LINQ, I've been thinking about this:
[for b in c
let d = f(b)
for e in g if h else m
where p(d, e): b, d, e]
as alternative syntax to Python's
((b, d, e)
for b in c
for d in [f(b)]
for e in (g if h else m)
if p(d, e))
This solves five problems in Python listcomp syntax:
1. The one this article is about, which is also a problem in SQL, as juancn points out.
2. The discontinuous scope problem: in Python
[Ξ for x in Γ for y in Λ]
x is in scope in Ξ and Λ but obviously not Γ. This is confusing and inconsistent.
3. The ambiguity between conditional-expression ifs and listcomp-filtering trailing ifs, which Python solves by outlawing the former (unless you add extra parens). This is confusing when you get a syntax error on the else, but there is no non-confusing solution except using non-conflicting syntax.
4. let. In Python you can write `for d in [f(b)]` but this is inefficient and borders on obfuscated code.
5. Tuple parenthesization. If the elements generated by your iteration are tuples, as they very often are, Python needs parentheses: [(i, c) for i, c in enumerate(s) if c in s]. That's because `[i, c` looks like the beginning of a list whose first two items are i and c. Again, you could resolve these conflicting partial parses in different ways, but all of them are confusing.