인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

정수연님의 프로필 이미지
정수연

작성한 질문수

파이썬입문과 크롤링기초 부트캠프 [파이썬, 웹, 데이터 이해 기본까지] (업데이트)

문제를 풀며 가장 자연스럽게 익숙해지는 파이썬 기본: 반복문 활용2

Exercise 38 질문

작성

·

215

1

Exercise 38. 데이터 구조와 반복문 (리스트)

  • 다음 리스트 변수에서 음수 데이터를 삭제하고, 양수만 가진 리스트 변수로 만들고, 해당 변수를 출력하세요.
num_list = [0, -11, 31, 22, -11, 33, -44, -55]

코드:

num_list = [0, -11, 31, 22, -11, 33, -44, -55]

for i in num_list:

    if i < 0:

        num_list.remove(i)

print(num_list)

실행 결과 : [0, 31, 22, 33, -55]

38번 문제를 풀기 위해서 위 코드와 같이 작성하였는데 -55가 왜 남아있는지 이해가 안가서 질문드립니다!

답변 3

1

네 내부적으로 인덱스 번호를 카운트해서 가지고 있습니다.

그래서 다음과 같이 enumerate 함수를 사용해서 싹 출력해보면,~~

num_list = [0, -11, 31, 22, -11, 33, -44, -55]

print (num_list)

for index, item in enumerate(num_list):

    print (index, num_list, item)

    if item < 0:

        num_list.remove(item)

마지막에 4번째로 인덱스 번호를 가지고 있었고, num_list는 5개로 줄어든 상황이라서,

마지막 -55를 체크할 반복문에서 0~4까지 5번 반복했고, num_list는 현재 5개이니, -55를 반복하지 않고, 종료되는 것이라고 보면 좋을 것 같습니다. 감사합니다.

0 [0, -11, 31, 22, -11, 33, -44, -55] 0
1 [0, -11, 31, 22, -11, 33, -44, -55] -11
2 [0, 31, 22, -11, 33, -44, -55] 22
3 [0, 31, 22, -11, 33, -44, -55] -11
4 [0, 31, 22, 33, -44, -55] -44

0

저도 강의를 듣고 있는 사람인데 질문을 보고 궁금해서 한번 해보다가 답글을 달아봅니다.
for i in num_list: 문장과 if i < 0: 문장 사이에 print(i)를 넣어서 출력을 해봤구요. 결과는 0, -11, 22, -11, -44가 나오네요.
 
제일 처음 제거되는 -11 뒤의 31, 그 다음 -11 뒤의 33, -44 뒤의 -55가 출력이 안되네요.
 
num_list.remove(i)가 실행될 때마다 for loop가 참조할 num_list가 갱신되면서 문제가 되는 것 같은데요.
 
for loop가 돌아갈때 num_list[0] = 0, num_list[1] = -11, num_list[2] = 22(-11이 제거되면서 인덱싱할 때 31은 뛰어넘음), num_list[3] = -11, num_list[4] = -44(마찬가지로 33을 뛰어넘음), 그리고 종료 (-11, -11, -44가 제거되고 나면 len(num_list) = 8 에서 len(num_list) = 5가 되므로 num_list[4]까지 접근하면 for loop가 종료된다. 이때 num_list[4] = -55가 된다.)
 
이렇게 돌아가는것 같은데... for loop가 list를 참조할 때 내부적으로 인덱스 번호를 카운트 해주는건지(?) 궁금하네요.

0

안녕하세요. 재미있는 현상이네요.

다음과 같이 코드를 바꿔서, 각 코드 라인별로 어떤 값이 변수에 들어가 있는지를 출력해보시면 이해가 가실 것 같습니다.

enumerate() 함수는 몇번째 횟수가 반복되고 있는지까지 리턴해줘요. 예를 들어,

for index, item in enumerate(num_list): <-- 이렇게 쓰면, index는 처음에는 0, 다음번에는 1, 이런식으로 횟수값이 들어가고, 실제 리스트 인덱스에 해당하는 값은 item에 들어갑니다.

remove 함수가 중간에 호출되면서, 해당 리스트 길이가 반복문 안에서 동적으로 줄어드는 바람에, 마지막에 -44 를 삭제했을 때, 전체 num_list 길이는 총 5개가 남고, 반복횟수도 0에서 4까지 5번을 한 상황이 되서, 더 이상 반복하지 않고, 종료가 된 것이예요. 그러니까 마지막 -55에 해당하는 반복을 처리하지 못한 셈이 됩니다. 그래서 -55가 남은 것입니다. 

반복횟수, 각 반복시마다 어떤 값이 변수에 들어있는지를 한번 모두 다음과 같이 출력해보시면 이해가 가실 것입니다.

마지막으로 개발자로 역량을 좀더 빠르게 기르시려면, 다음과 같이 두 가지만 꼭 생각해두시고 습관화해보세요. 이 두가지가 장기적으로 매우 큰 도움이 되실꺼예요~~

이후에도 코드 동작이 이해가 안가면, 무조건 라인마다 최대한 각 변수값을 출력해보세요. 그러면 이해하시는데 큰 도움이 되실 것이구요. 중간 변수값들을 확인하는데 역시 주피터 노트북이라는 툴이 매우 유용하다는 것도 깨달으실 수 있으실 것 같습니다. 

다음으로 이래도 이해가 안가면, 다음에는 google 사이트에서 여러 키워드를 넣어가며 검색해보세요. 분명히 유사한 케이스에 대한 답을 얻으실 수 있으실꺼예요.

감사합니다. 

테스트 코드도 첨부드립니다.

num_list = [0, -11, 31, 22, -11, 33, -44, -55]

print (num_list)

for index, item in enumerate(num_list):

    print (index, num_list, item)

    if item < 0:

        num_list.remove(item)

정수연님의 프로필 이미지
정수연

작성한 질문수

질문하기