Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering two lists simultaneously

I have three lists:

del_ids = [2, 4]
ids = [3, 2, 4, 1]
other = ['a', 'b', 'c', 'd']

and my goal is to remove del_ids with the result being

ids = [3, 1]
other = ['a', 'd']

I have tried to do a mask for elements to keep (mask = [id not in del_ids for id in ids]) and I plan to apply this mask on both lists.

But I feel that this is not a pythonic solution. Can you please tell me how I can do this better?

like image 971
Barney Szabolcs Avatar asked Aug 01 '13 13:08

Barney Szabolcs


4 Answers

zip, filter and unzip again:

ids, other = zip(*((id, other) for id, other in zip(ids, other) if id not in del_ids))

The zip() call pairs each id with the corresponding other element, the generator expression filters out any pair where the id is listed in del_ids, and the zip(*..) then teases out the remaining pairs into separate lists again.

Demo:

>>> del_ids = [2, 4]
>>> ids = [3, 2, 4, 1]
>>> other = ['a', 'b', 'c', 'd']
>>> zip(*((id, other) for id, other in zip(ids, other) if id not in del_ids))
[(3, 1), ('a', 'd')]
like image 80
Martijn Pieters Avatar answered Nov 10 '22 22:11

Martijn Pieters


zip, filter, unzip :

ids, other = zip(*filter(lambda (id,_): not id in del_ids, zip(ids, other)))
like image 23
Julien Grenier Avatar answered Nov 10 '22 23:11

Julien Grenier


In order to avoid learning tricky syntax, do it in two steps.

other = [o for my_id, o in zip(ids, other) if my_id not in del_ids]
ids = [my_id for my_id in ids if my_id not in del_ids]

Drawback
You must execute the statements in correct order, so there's risk of bugs if for some reason the order changes.

Advantage
It's straight forward, so you don't have to search Stackoverflow next time you want to do it.

like image 2
Teitur Avatar answered Nov 10 '22 21:11

Teitur


Converting to pandas data frame and applying the mask:

del_ids = [2, 4]
ids = [3, 2, 4, 1]
other = ['a', 'b', 'c', 'd']
df = pd.DataFrame({'ids':ids,'other':other})
df = df[~df.ids.isin(del_ids)]
ids = df['ids'].tolist()
other = df['other'].tolist()
like image 1
Sam S. Avatar answered Nov 10 '22 23:11

Sam S.