简体   繁体   中英

In Python, how can I remove a certain element from a list of lists?

Say I have a list of lists:

x = [[1,0,0,3],[1,1,1,1],[5,2,0,0],[4,3,0,1],[0,0,0,0]

How can I create a new list that only contains the non-zero terms of each list, such that

y = [[1,3],[1,1,1,1],[5,2],[4,3,1],[]]
In [23]: x = [[1,0,0,3],[1,1,1,1],[5,2,0,0],[4,3,0,1],[0,0,0,0]]

In [24]: y = [[el for el in l if el != 0] for l in x]

In [25]: y
Out[25]: [[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]

Alternatively,

In [28]: [filter(None, l) for l in x]
Out[28]: [[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]

Or using functools :

In [32]: map(functools.partial(filter, None), x)
Out[32]: [[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]

Use list comprehensions :

>>> [[i for i in j if i] for j in x]
[[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]

Also, note, that I fell back on the fact, that integers int are promoted to false only when they are equal to 0 , and they are true of they are not equal to 0 . It is worth contemplating if it would be wise to use if i != 0 instead of if i , as the former is more explicit and thus more Pythonic.

You can filter the lists:

y = map(lambda l: filter(None, l), x)

Or you can use partial :

from functools import partial

y = map(partial(filter, None), x)
x = [[1,0,0,3],[1,1,1,1],[5,2,0,0],[4,3,0,1],[0,0,0,0]]

print x
print 'id(x) ==',id(x)
for sublist in x:
    print map(id,sublist)

for sublist in x:
    for i in xrange(len(sublist)-1,-1,-1):
        if sublist[i]==0:
            del sublist[i]

print
print x
print 'id(x) ==',id(x)
for sublist in x:
    print map(id,sublist)

With this code, you really ELIMINATE the zeros FROM THE INITIAL list without having to create another list, that is to say this code acts in place in x

The printing of id(x) and map(id,sublist) is done to show this way of modification:
the identities, that is to say the adresses of the elements of the sublists (for the ones that remain), and of the list x itself, are the same before and after the treatment

If the list is big, it may be interesting to modify it in place.
If it is not the case, you can use the other solutions that all create a new list object.

The indexes are run in the reverse sense thanks to xrange(len(sublist)-1,-1,-1) because if the list was explored from left to right, it would give erroneous result

Result

[[1, 0, 0, 3], [1, 1, 1, 1], [5, 2, 0, 0], [4, 3, 0, 1], [0, 0, 0, 0]]
id(x) == 18725984
[10021864, 10021876, 10021876, 10021840]
[10021864, 10021864, 10021864, 10021864]
[10021816, 10021852, 10021876, 10021876]
[10021828, 10021840, 10021876, 10021864]
[10021876, 10021876, 10021876, 10021876]

[[1, 3], [1, 1, 1, 1], [5, 2], [4, 3, 1], []]
id(x) == 18725984
[10021864, 10021840]
[10021864, 10021864, 10021864, 10021864]
[10021816, 10021852]
[10021828, 10021840, 10021864]
[]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM