Frage

I was iterating through a list with a for loop, when I realized del seemed to not work. I assume this is because i is representing an object of the for loop and the del is simply deleting that object and not the reference.

And yet, I was sure I had done something like this before and it worked.

alist = [6,8,3,4,5]  

for i in alist:  
    if i == 8:  
        del i  

In my code its actually a list of strings, but the result is the same: even though the if conditional is satisfied, deleting i has no effect.

Is there a way I can delete a number or string in this way? Am I doing something wrong?

Thanks.

War es hilfreich?

Lösung

Your idea as to why you are seeing that behavior is correct. Hence, I won't go over that.

To do what you want, use a list comprehension to filter the list:

>>> alist = [6,8,3,4,5]
>>> [x for x in alist if x != 8]
[6, 3, 4, 5]
>>> alist = [6,8,8,3,4,5]
>>> [x for x in alist if x != 8]
[6, 3, 4, 5]
>>>

This approach is also a lot more efficient than a for-loop.

Andere Tipps

The for loop assigns a new value to i at each run.

So, essentially, your for loop above does

i = 6
i = 8
del i
i = 3
i = 4
i = 5

which has no effect.

del does not delete an object. It simply decrements the reference count of the object referenced by its argument. In your code

alist = [6,8,3,4,5]  

for i in alist:  
    if i == 8:  
        del i

you have 6 objects: 5 separate integers, and a list of 5 references (one per integer). The for loop works by executing its body once per element in alist, with i holding a reference to a different element in alist in each iteration. Whichever object is referenced by i has a reference count of at least 2: the reference held by alist and i itself. When you call del i, you are simply decrementing its reference count by making i point to nothing.

While the following techinically works, by deleting all (known) references to the object, it has its own problems (involving modifying a list you are currently iterating over) and should not be used.

>>> alist=[6,8,3,4,5]
>>> for i, a in enumerate(alist):
...   if a == 8:
...     del a        # delete the loop index reference
...     del alist[i] # delete the reference held by the list
>>> alist
[6,3,4,5]

Instead, simply use a list comprehension to build a new list to replace the old one

alist = [ x for x in alist if x != 8 ]

If you really want to use del you need to use it on the list:

del alist[i]

(note that in this case i is an index, not the value you want to remove)

But really here you should probably just create another list using list comprehension:

[x for x in alist if x != 8]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top