Anything more will come back to bite you later.
[x for x in y if x is not z]
Sometimes though, facilitated by Jupyter's notebooks making executing as you build the code very easy, I create a beast like this: [os.path.join([x for x in y if x is not z]) + '/bin' for a in b if 'temp' not in a]
Yes this is fictional and probably contains an error but you get the point, you can filter lists of lists like this, but it's really unfriendly to anyone trying to understand it later.Although, personally, I enjoy python list comprehensions.
That's one expression because it used to be part of a giant comprehension, but I moved it into a function for a bit more readability. I'm considering moving it back just for kicks though.
My philosophy is: if you're only barely smart enough to code it, you aren't smart enough to debug it. Therefore, you should code at your limit, to force yourself to get smarter while debugging
tags = list(set([
nel
for subli in [
mel
for subl in [
[[jel.split('/')[2:] for jel in el]
for el in classified
]
for mel in subl
]
for nel in subli
if nel
]))
Still not very readable, tho. But that's largely due to Python's outputs-first sequence comprehension syntax being a mess that doesn't scale at all.Side note: one other thing I always hated about those things in Python is that there's no way to bind an intermediary computation to a variable. In C# LINQ, you can do things like:
from x in xs
let y = x.ComputeSomething()
where y.IsFoo && y.IsBar
select y
In Python, you have to either invoke ComputeSomething twice, or hack "for" to work like "let" by wrapping the bound value in a container: y
for x in xs
for y in [x.ComputeSomething()]
if y.IsFoo and y.IsBar
It's not just about not repeating yourself or not running the same code twice, either - named variables are themselves a form of self-documenting code, and a sequence pipeline using them even where they aren't strictly needed can be much more readable. y
for x in xs
if (y:=x.ComputeSomething()).IsFoo and y.IsBar[(y:=x.ComputeSomething()) for x in xs if y.IsFoo and y.IsBar]
Choices like wrapping a set constructor around a list comprehension rather than just using a set comprehension don't help, neither does using multiple nested no-transformation comprehensions laid out that way.
By hand, on mobile, I think this reduces to (assuming “from itertools import chain” in the file header):
tags = list({
nel
for subli in chain.from_iterables(chain(
[[jel.split('/')[2:] for jel in el]
for el in classified))
for nel in subli
if nel
}) ys = (x.ComputeSomething() for x in xs)
result = [y for y in ys if y.isFoo and y.isBar] [x for stop in range(5) for x in range(stop)]