Delete many elements of list (python)

前端 未结 5 1395
小蘑菇
小蘑菇 2021-02-07 08:03

I have a list L.

I can delete element i by doing:

del L[i]

But what if I have a set of non contiguous indexes to delete?



        
相关标签:
5条回答
  • 2021-02-07 08:29
    L = [ item for item in L if L.index(item) not in I ]
    
    0 讨论(0)
  • 2021-02-07 08:31

    You can use numpy.delete as follows:

    import numpy as np
    a = ['a', 'l', 3.14, 42, 'u']
    I = [1, 3, 4]
    np.delete(a, I).tolist()
    # Returns: ['a', '3.14']
    

    If you don't mind ending up with a numpy array at the end, you can leave out the .tolist(). You should see some pretty major speed improvements, too, making this a more scalable solution. I haven't benchmarked it, but numpy operations are compiled code written in either C or Fortran.

    0 讨论(0)
  • 2021-02-07 08:31

    If your original list data can safely be turned into a set (i.e. all unique values and doesn't need to maintain order), you could also use set operations:

    Lset = set(L)
    newset = Lset.difference(I)
    

    You could also maybe do something with a Bag/Multiset, though it probably isn't worth the effort. Paul McGuire's second listcomp solution is certainly best for most cases.

    0 讨论(0)
  • 2021-02-07 08:42

    Eine Minuten bitte, Ich hap eine kleine Problemo avec diese Religione. -- Eddie Izzard (doing his impression of Martin Luther)

    Deleting by reverse-iterating over a list to preserve the iterator is a common solution to this problem. But another solution is to change this into a different problem. Instead of deleting items from the list using some criteria (in your case, the index exists in a list of indexes to be deleted), create a new list that leaves out the offending items.

    L[:] = [ item for i,item in enumerate(L) if i not in I ]
    

    For that matter, where did you come up with the indexes in I in the first place? You could combine the logic of getting the indexes to be removed and building the new list. Assuming this is a list of objects and you only want to keep those that pass an isValid test:

    L[:] = [ item for item in L if item.isValid() ]
    

    This is much more straightforward than:

    I = set()
    for i in range(len(L)):
        if not L[i].isValid():
            I.add(i)
    
    for i in sorted(I, reverse=True):
        del L[i]
    

    For the most part, I turn any question about "how to delete from a list the items that I don't want" into "how to create a new list containing just the items I want".

    EDITED: changed "L = ..." to "L[:] = ..." per Alex Martelli's answer to this question.

    0 讨论(0)
  • 2021-02-07 08:45
    for i in I:
        del L[i]
    

    won't work, because (depending on the order) you may invalidate the iterator -- this will usually show up as some items which you intended to delete remaining in the list.

    It's always safe to delete items from the list in the reverse order of their indices. The easiest way to do this is with sorted():

    for i in sorted(I, reverse=True):
        del L[i]
    
    0 讨论(0)
提交回复
热议问题