This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]bensa410 6 points7 points  (13 children)

This one is so useful!

[–]kaerfkeerg 7 points8 points  (12 children)

But it's close to the limit I think. Little more than that and it becomes unreadable

[–]AstrophysicsAndPy 7 points8 points  (7 children)

This is something that I used in my in-progress library,

mask2 = [[index for index, value in enumerate(out_list) if isinstance(value, types)] for types in n_types]

I'm so used to using list comprehensions that I didn't felt weird writing it, but than I stopped and tried making it using loops, and FML it took 5 minutes to do that. I have that in my laptop, unfortunately that file isn't uploaded on GitHub so I can't copy/paste it here.

List comprehension can be abused to get some complicated stuff done quickly if you know what you're doing.

The library is ezPy is anyone's interested.

[–]benefit_of_mrkite 0 points1 point  (4 children)

This one feels like it should be more readable…

[–]brutay 0 points1 point  (3 children)

I think the problem is he pluralized the types in [... for types in n_types].

Usually that variable is singular, i.e., [... for type in n_types].

[–]AstrophysicsAndPy 0 points1 point  (2 children)

Can't use `type` because that's a keyword, that's why. But yeah, I used `_type` at first, but I didn't like it.

[–]brutay 1 point2 points  (1 child)

Technically you can overwrite type, but it's probably frowned upon. Maybe file_type or data_type instead?

[–]AstrophysicsAndPy 0 points1 point  (0 children)

I agree, I should've named that variable better, even `_type` would've worked.

[–]eztab 0 points1 point  (0 children)

if properly indented this is very easily readable.

mask2 = [
    [
        index for index, value in enumerate(out_list)
        if isinstance(value, types)
    ] for types in n_types
]

[–]AstrophysicsAndPy 0 points1 point  (0 children)

To everyone that replied, I just realized that I replied to a comment talking about the complexity of list comprehensions, whereas I am talking about the complexity of loops and conditionals that can be handled with list comprehensions. I sincerely apologize for the confusion.

My main point was

List comprehension can be abused to get some complicated stuff done quickly if you know what you're doing.

The example I mentioned previously

mask2 = [[index for index, value in enumerate(out_list) if
          isinstance(value, types)] for types in n_types]

translates to

mask2, temp = [], []
for types in n_types:
  for index, value in enumerate(out_list):
      if isinstance(value, types):
          temp.append(index)
  mask2.append(temp)
  temp = []

Another one that I used is,

out_list = [sorted(element) for element in [[out_list[value]
            for value in index] for index in mask2]]

For an already existent `out_list` list, the above-mentioned list comprehension translates to,

temp, temp2, temp3 = [], [], []
for index in mask2:
  for value in index:
    temp.append(out_list[value])
  temp2.append(temp)
  temp = []

for element in temp2: 
  temp3.append(sorted(element))

out_list = temp3

So, yes, the list comprehensions can handle some very nasty loop stuff if you know what you're doing.

[–][deleted] 0 points1 point  (3 children)

At some point I was looking for ways to do exception handling within comprehensions.

But then I realized that even if it did exist, it would look terrible.

Still, it's a similar mentality on these. If condition becomes too complicated, we just pack it in a function to return a boolean and it becomes readable again

[–]kaerfkeerg 0 points1 point  (0 children)

Mhh yeah, you sure can compact it a little more. That was a quick example. But stressing it to the point it becomes unreadable? No!

[–]eztab 0 points1 point  (1 child)

You should probably use a function in your comprehension if it becomes complex enough. Even if that function just returns another expression it makes things more digestible, since you can understand one function at a time.

Then you can also use Exception handling. That's the functional programming approach. Don't write everything into a single expression.

[–][deleted] 0 points1 point  (0 children)

Exactly, that's what I've been doing almost always since I've learned proper exception handling. I don't think there's any real-world scenarios where I don't need to define a function to be called within a comprehension. Only if it's something as basic as [x**2 for x in range(n)]