본문 바로가기

Python Basic/혼공파

[혼공파] Chapter 04 반복문 ④문자열, 리스트, 딕셔너리와 관련된 기본 함수


  • 는 개념 정리
  •  개인적으로 새롭게 알게 된 점 

다루는 내용: 

reversed(), 제너레이터&이터레이터, 확장 슬라이싱, enumerate(), 리스트 내포

itmes() 함수

reversed()

  • 리스트에서 요소의 순서를 뒤집고 싶을 때는 reversed() 함수 사용
  • reversed() 함수의 매개변수에 리스트를 넣으면 리스트를 뒤집을 수 있음.  

CODE

# 리스트를 선언하고 뒤집음.
list_a = [1,2,3,4,5]
list_reversed = reversed(list_a)

print('# reversed() 함수')
print(list_reversed)
print(list(list_reversed))
print()

print('# reversed() 함수와 반복문')
# 첫 번째 반복문
for i in reversed(list_a):
    print(i)
    
# 두 번째 반복문
for i in reversed(list_a):
    print(i)

OUTPUT

# reversed() 함수
<list_reverseiterator object at 0x031F21D0>
[5,4,3,2,1]

# reversed() 함수와 반복문
5
4
3
2
1
  • list_reversed를 출력하면, 리스트가 아니라 <list_reversediterator object at (주소)> 가 출력됨
  • '첫 번째 반복문' 부분만 실행됨. '두 번째 반복문' 부분은 출력되지 않음. 

제너레이터 & 이터레이터

  • 이터러블 (iterable): 반복할 수 있는 것. 
    • 즉, 이터러블은 내부에 있는 요소들을 차례차례 꺼낼 수 있는 객체를 의미. 
    • 리스트, 딕셔너리, 문자열 튜플 등은 모두 내부에서 요소를 차례차례 꺼낼 수 있으므로 이터러블임. 
  • 이터레이터 (iterator) 
    • 이터러블 중에서 next() 함수를 적용해 하나하나 꺼낼 수 있는 요소를 이터레이터라고 함.
    • e.g. iter(list): list를 iter로 통하여 이터레이터를 만들었음. list는 반복가능하지만 이터레이터는 아님. 명시적으로 반복가능한객체로 만들어서 사용해줘야 함. 
  • iter() 
    • list나 dict을 이터레이터로 만들어주는 함수
    • e.g. a라는 dict 을 생성하여 iter함수를 통해 b라는 이터레이터를 만들어 줌. 

CODE 1

a  = {1: 'a', 2: 'b'}
print(a.__class__)

b = iter(a)
print(b.__class__)

OUTPUT 1

<class 'dict'>
<class 'dict_keyiterator'>

 

CODE 2

a.next()

OUTPUT 2

ArrtibuteError: 'dict' object has no attribut 'next'

 

+추가) next() 함수 

github.com/cherrypy/cherrypy/issues/1408

AttributeError

예외) AttributeError: 'list_iterator' object has no attribute 'next' 발생. 

=> python2에서는 iterator.next() 함수 사용이 가능한데, python3에서는 지원하지 않음. 

 

python3 에서는 next(iterator 객체) 혹은 iterator.__next__() 사용.

 

  • 제너레이터 (generator)
    • 이터레이터를 만들어 주는 것, iterator를 생성해주는 함수. 즉, 반복 가능한 객체를 만들어주는 행위 
    • generator는 일반적인 함수와 비슷하게 보이지만, 가장 큰 차이점은 yield 키워드. 

Q1. list_reversed를 출력하면, 리스트가 아니라 <list_reversediterator object at (주소)> 가 출력됨

Q2. '첫 번째 반복문' 부분만 실행됨. '두 번째 반복문' 부분은 출력되지 않음. 

 

A1. reversed() 함수의 리턴값이 'reverseiterator'로 '이터레이터' 이기 때문. 

A2. for 반복문의 매개변수에 넣으면 반복할 때마다 요소를 하나하나 꺼내주는 것. 따라서 첫 번째 for 반복문에서 모든 요소를 꺼냈기 때문에 두 번째 for 반복문이 실행되지 않음. 

 

* reversed() 함수는 메모리의 효율성을 위해서 리스트를 바로 리턴하지 않고, 이터레이터를 리턴함. *

* 1만 개의 요소가 들어 있는 리스트를 복제한 뒤, 뒤집어서 리턴 하는 것보다

기존에 있던 리스트를 활용해서 작업하는 것이 훨씬 효율적이라고 판단하기 때문 *

확장 슬라이싱

  • 리스트를 뒤집을 수 있는 방법
  • 리스트에 [::-1] 을 붙이면 리스트의 내용이 뒤집힘. 
    • 문자열에도 적용 가능
  • 비파괴적 코드이므로 원본에는 영향이 없음

CODE

numbers = [1, 2, 3, 4, 5]
print(numbers)
print(numbers[::-1])

OUTPUT

[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]

enumerate()

  • 리스트의 요소를 반복할 때, 현재 인덱스가 몇 번째인지 확인하기 위한 파이썬 제공 함수

CODE

example_list = ['요소A', '요소B', '요소C']

# 단순 출력
print(example_list)
print()

#enumerate() 함수를 적용해 출력
print(enumerate(example_list))
print()

#list() 함수로 강제 변환해 출력
print(list(enumerate(example_list)))
print()

#for 반복문과 enumerate() 함수 조합해서 사용
for i, value in enumerate(example_list):
    print("{} 번째 요소는 {} 입니다.".format(i, value))
    

OUTPUT

['요소A', '요소B', '요소C']

<enumerate object at 0x02A43CB0>

[(0, '요소A'), (1, '요소B'), (2, '요소C')]

0 번째 요소는 요소A 입니다.
1 번째 요소는 요소B 입니다.
2 번째 요소는 요소C 입니다.
  • enumerate() 함수의 return 값이 이터레이터

리스트 내포

  • 프로그램을 만들 때는 반복문을 사용해 리스트를 재조합하는 경우가 많음.
  • e.g. range(0, 20, 0)로 0부터 20 사이의 짝수를 구한 뒤, 제곱해서 새로운 리스트를 만드는 코드

CODE

array = []

for i in range(0, 20, 2):
    array.append(i * i)
    
print(array)

OUTPUT

[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]

다음과 같이 한 줄로 작성할 수 있고, 다음과 같은 구문을 리스트 내포라고 함. 

 

CODE

리스트 이름 = [표현식 for 반복자 in 반복할 수 있는 것]
array = [i * i for i in range(0, 20, 2)]

딕셔너리의 items() 함수와 반복문 조합

enumerate() 함수와 반복문을 조합해서 for i, value in enumerate(리스트) 형태로 반복문을 작성할 수 있었던 것처럼 딕셔너리는 items() 함수와 함께 사용하면 키와 값을 조합해서 쉽게 반복문을 작성할 수 있음.