Usuwanie elementów z listy podczas iterowania po niej

Data publikacji: 2015-01-06 | Tagi:

Załóżmy, że mamy listę i chcemy iterując po niej usuwać z niej niektóre elementy. Niby prosta sprawa, ale...

... przy iterowaniu po liście usuwamy z nej elementy, przez co zaburzamy jej układ, przez co pomijamy niektóre elementy, oto przykładowy kod:

In [1]: a = ['aa', 'bb', '0', 'cc', '1', '2', '3', 'dd', 'ee', '4', '5', 'ff', ]

In [2]: for e in a:
            if e.isdigit():
            a.remove(e)
        ...:         

In [3]: a
Out[3]: ['aa', 'bb', 'cc', '2', 'dd', 'ee', '5', 'ff']

Na powyższym przykładzie widać, że niektóre elementy, które są w 100% liczbami ('2', '5') nie zostały uwzględnione w iteracji - pętla usuwając elementy nie przesuwała razem z nimi indeksu listy, bo niby dlaczego miałaby to robić?

Jak zatem do tego podejść? Operować na kopii listy:

elements = ['a', '01', 'b', '033a', '654', '23', '44', ]

for element in list(elements):
    if element.isdigit():
        elements.remove(element)

W tym momencie iterujemy po kopii listy, ale elementy usuwamy z niej samej.

Oczywiście w pythonie nie można zrobić tak:

lista1 = lista2
for element in lista2...

lista1 oraz lista2 są dwiema nazwami tego samego obiektu listy, więc tutaj nam się nic nie zmienia. Należy użyć jawnej kopii obiektu.

Pozostaje jeszcze małe pytanie - jak sprawdzić czy dwie nazwy są nazwami tego samego obiektu, czy innego? Dokonuje się tego poprzez użycie operatora is.

In [1]: x = [1, 2, 3]

In [2]: y = x

In [3]: y == x
Out[3]: True

In [4]: y is x
Out[4]: True

In [5]: x == list(x)
Out[5]: True

In [6]: x is list(x)
Out[6]: False

Operator == zwraca True jeśli zawartość obu obiektów jest sobie równa niezależnie od tego czy jest to jeden obiekt czy dwa różne. Natomiast operator is zwraca True tylko wtedy, gdy obiekt pierwszy jest obiektem drugim.


Oceń ten post:
Podziel się:

comments powered by Disqus

IT w obrazkach: