3

I have a parent list called parent_list, and two subsets via which I'm to filter the parent_list. These subsets are also python lists, and they're called filter1 and filter2.

Can I do:

final_list = [object for object in parent_list if object.pk not in filter1 or filter2]

Or will I need to do this filteration separately, as in:

intermediate_list = [object for object in parent_list if object.pk not in filter1]
final_list = [object for object in intermediate_list if object.pk not in filter2]

I couldn't explicitly find the answer from the documentation on python list comprehensions.

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
Hassan Baig
  • 15,055
  • 27
  • 102
  • 205

3 Answers3

6

Use sets for fast look up of the items:

final_list = [object for object in parent_list if object.pk not in set(filter1 + filter2)]
#                                                                   ^ 

The size of the entire search space is also reduced as duplicate items are removed from the set.

Found this somewhere on SO:

Sets are implemented using hash tables. Whenever you add an object to a set, the position within the memory of the set object is determined using the hash of the object to be added. When testing for membership, all that needs to be done is basically to look if the object is at the position determined by its hash, so the speed of this operation does not depend on the size of the set. For lists, in contrast, the whole list needs to be searched, which will become slower as the list grows.

Community
  • 1
  • 1
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • Two follow up questions: **1)** do I need to convert the set to a list (i.e. list(set(filter1+filter2)) for this to work **2)** this sort of a thing won't work with ValuesQuerySet would it? – Hassan Baig Jun 16 '16 at 19:05
  • 2
    Force the QuerySets to evaluate their items by slicing: `set(filter1[:] + filter2[:])`. You don't need to convert the `set` to a `list`. – Moses Koledoye Jun 16 '16 at 19:08
1

I think you can do it as below:

final_list = [object for object in parent_list if (object.pk not in filter1) and (object.pk not in filter2)]

I recomend make two sets filter1 and filter2 with the object.pk to be filtered just bc getting an element from a set it's faster

Mahendra Gaur
  • 380
  • 2
  • 11
1

You can also use:

final_list = [object for object in parent_list if object.pk not in filter1+filter2]
Nikign
  • 379
  • 3
  • 9