Deleting more than one element from a list

C

candide

Is the del instruction able to remove _at the same_ time more than one
element from a list ?


For instance, this seems to be correct :

>>> z=[45,12,96,33,66,'ccccc',20,99]
>>> del z[2], z[6],z[0]
>>> z [12, 33, 66, 'ccccc', 20]
>>>


However, the following doesn't work :
>> z=[45,12,96,33,66,'ccccc',20,99]
>>> del z[2], z[3],z[6]
Traceback (most recent call last):


Does it mean the instruction

del z[2], z[3],z[6]

to be equivalent to the successive calls


del z[2]
del z[3]
del z[6]

?
 
G

Gary Herron

candide said:
Is the del instruction able to remove _at the same_ time more than one
element from a list ?


For instance, this seems to be correct :

z=[45,12,96,33,66,'ccccc',20,99]
del z[2], z[6],z[0]
z [12, 33, 66, 'ccccc', 20]


However, the following doesn't work :
z=[45,12,96,33,66,'ccccc',20,99]
del z[2], z[3],z[6]
Traceback (most recent call last):


Does it mean the instruction

del z[2], z[3],z[6]

to be equivalent to the successive calls


del z[2]
del z[3]
del z[6]

Yes, those are equivalent. The reason it fails is that, by the time it
gets around to the third delete, there is no longer in index [6] in the
list. The element you were thinking of is now at index [4].

This, however, will work as you expected:

del z[6], z[3],z[2]
 
M

Mensanator

Is the del instruction able to remove _at the same_ time more than one
element from a list ?

For instance, this seems to be correct :

 >>> z=[45,12,96,33,66,'ccccc',20,99]
 >>> del z[2], z[6],z[0]
 >>> z
[12, 33, 66, 'ccccc', 20]
 >>>

However, the following doesn't work :

 >> z=[45,12,96,33,66,'ccccc',20,99]
 >>> del z[2], z[3],z[6]
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
 >>>

Does it mean the instruction

del z[2], z[3],z[6]

to be equivalent to the successive calls

del z[2]
del z[3]
del z[6]

That's part of the problem. Let's look at a better example.
z = [0,1,2,3,4,5,6]
del z[0],z[3],z[6]
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
del z[0],z[3],z[6]
IndexError: list assignment index out of range[1, 2, 3, 5, 6]

Yes, the error was caused by the list shrinking between calls,
so the 6 did not get deleted. But notice that 3 is still there
and 4 is missing.

If you must delete this way, do it bottom up so that the index
remains valid for the subsequent calls:
z = [0,1,2,3,4,5,6]
del z[6],z[3],z[0]
z
[1, 2, 4, 5]
 
E

Emile van Sebille

On 4/21/2010 12:56 PM candide said...
Is the del instruction able to remove _at the same_ time more than one
element from a list ?


For instance, this seems to be correct :

z=[45,12,96,33,66,'ccccc',20,99]

Not as I see it -- watch your index values - they change after each
delete is completed. It'll work if you order them backwards though.
>>> a = range(10)
>>> del a[0],a[2],a[4],a[6]
>>> a [1, 2, 4, 5, 7, 8]
>>> a = range(10)
>>> del a[6],a[4],a[2],a[0]
>>> a [1, 3, 5, 7, 8, 9]
>>>

Emile
 
R

Raymond Hettinger

Is the del instruction able to remove _at the same_ time more than one
element from a list ?

For instance, this seems to be correct :

 >>> z=[45,12,96,33,66,'ccccc',20,99]
 >>> del z[2], z[6],z[0]
 >>> z
[12, 33, 66, 'ccccc', 20]
 >>>

However, the following doesn't work :

 >> z=[45,12,96,33,66,'ccccc',20,99]
 >>> del z[2], z[3],z[6]
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
 >>>

Does it mean the instruction

del z[2], z[3],z[6]

to be equivalent to the successive calls

del z[2]
del z[3]
del z[6]

?

Looks like you got a lot of good answers to the question as asked.

FWIW, successive delete operations on a list are dog slow.
It is better to delete all of the entries in one pass.
There are several ways to do it. Here's one:
z=[45,12,96,33,66,'ccccc',20,99]
targets = [2, 3, 6]
PLACEHOLDER = object()
for i in targets: .... z = PLACEHOLDER
z[:] = [elem for elem in z if elem is not PLACEHOLDER]


Here's another:
z=[45,12,96,33,66,'ccccc',20,99]
targets = set([2, 3, 6])
z[:] = [elem for i, elem in enumerate(z) if i not in targets]

Besides being scaleable, these two examples have some nice learning
points. Hopefully, you will find them useful.


Raymond
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top