Nick
Nick

Reputation: 10499

How to improve this list comprehension

I need to evaluate the following list comprehension:

[r for r in listOfList if
  1 not in [lst[i] for i in r] and
  0 in     [lst[i] for i in r]
]

That is, I need to get as result a list of lists (of numbers), where each of them has no element equal to 1, but at least one element equal to 0.
As you can see there is the repetition of [lst[i] for i in r].
Is there a way to improve the evaluation of my list comprehension?

Examples:

listOfList = [[0, 1, 2], [3, 4, 5], [6, 7, 8], 
[0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]

lst = [0, 1, None, None, None, 1, None, None, 0]

Upvotes: 0

Views: 79

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121924

You can use a nested loop to compute the sub-set from lst first, or you can use the any() function to use a generator expression and limit the number of iterations:

Using a nested list loop:

[r for r in listOfList 
   for indexed in ({lst[i] for i in r},)
   if 1 not in indexed and 0 in indexed]

I also changed the sub-set from lst to a set to make use of faster constant time membership tests.

Using any():

[r for r in listOfList 
   if not any(lst[i] == 1 for i in r) and
      any(lst[i] == 0 for i in r)]

any() will stop iterating over the generator the moment an expression that evaluates to True is encountered.

Upvotes: 2

Related Questions