본문 바로가기

Linux

[python] list로 for문 돌면서 remove할때 주의할점

반응형

원래 리스트를 for 문을 돌면서 원소를 하나씩 제거하려고 했는데 원하는 대로 되지 않았다. 문제는 다음과 같았다.

 

리스트를 돌면서 원소를 제거할때

>>> l = [1, 2, 3, 4, 5]
>>>
>>> for i in l:
...     print(i)
...     l.remove(i)
...
1
3
5

 

리스트 l에 있는 원소를 for루프를 돌면서 지우기 위해 위와 같은 코드가 있다고 하면,

모든 원소를 루프를 돌지 않게 된다.

결국 l의 모든 원소는 모두 지워지지 않고 남는 원소들이 생긴다.

 

>>> for i in range(0, len(l)):
...     print(l[i])
...
2
4

 

문제의 원인은 remove시 원본 리스트 데이터도 훼손되기 때문에 발생한다. 

 

1번째 루프에서 0번째 원소 1을 지우므로 리스트는 [2. 3. 4. 5]가 된다.

2번째 루프에서 1번째 원소를 가져오는데 이는 3이 된다. 즉 2는 건너 뛰게 된다.

이렇게 되면서 누락이 발생한다.

이를 위해서는 리스트를 카피하는 방식으로 원하는 대로 반복문을 돌 수 있게 수정했다.

 

>>> l = [1,2,3,4,5]
>>> for i in l[:]:
...    print(i)
...    l.remove(i)
...
1
2
3
4
5
>>> l
[]

 

l[:]을 통해 l의 복사본을 루프에 넣고 돌리는 방식이다.

다행히 원하는 결과를 얻을 수 있었다.

 

for문에 들어가는 리스트가 기본적으로 복사본이 아니라 원본이기 때문에, 

데이터 원소를 주의해야 한다.

반응형