Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove elements from several lists simultaneously

Tags:

python

I have three lists with the same length and another list that stores indexes of elements that I need to remove from all three lists. This is an example of what I mean:

a = [3,4,5,12,6,8,78,5,6]
b = [6,4,1,2,8,784,43,6,2]
c = [8,4,32,6,1,7,2,9,23]

(all have len()=9)

The other list contains the indexes of those elements I need to remove from all three lists:

d = [8,5,3]

(note that it is already sorted)

I know I can remove one element at the time from the three lists with:

for indx in d:
    del a[indx]
    del b[indx]
    del c[indx]

How could I do this in one single line?

like image 715
Gabriel Avatar asked Jan 16 '26 18:01

Gabriel


2 Answers

Not one line, but concise, readable, and completely idiomatic Python:

for indx in d:
    for x in a, b, c:
        del x[indx]

However, the fact that you're doing this in the first place implies that maybe rather than 3 separate list variables, you should have a list of 3 lists, or a dict of three lists keyed by the names 'a', 'b', and 'c'.


If you really want it in one line:

for indx in d: a.pop(indx), b.pop(indx), c.pop(indx)

But that's really terrible. You're calling pop when you don't care about the values, and building up a tuple you don't need.

If you want to play code golf, you can save a few characters by using a list comprehension—which adds one more language abuse, and builds another, larger object you don't actually want—as in Ioan Alexandru Cucu's answer:

[x.pop(indx) for indx in d for x in a, b, c]

Of course the best way to write it in one line is to factor it out into a function:

def delemall(indices, *lists):
    for index in indices:
        for x in lists:
            del x[indx]

And now, each of the 300 times you need to do this, it's just:

delemall(d, a, b, c)
like image 117
abarnert Avatar answered Jan 19 '26 20:01

abarnert


I think just your code is OK, to make it a single line:

In [234]: for i in d: del a[i], b[i], c[i]

In [235]: a,b,c
Out[235]: ([3, 4, 5, 6, 78, 5], [6, 4, 1, 8, 43, 6], [8, 4, 32, 1, 2, 9])

but I still like leaving that for loop two lines ;)

like image 33
zhangxaochen Avatar answered Jan 19 '26 19:01

zhangxaochen