티스토리 뷰

python lecture/basic

[edu] for문 (반복문, range)

burningrizen 2019. 2. 28. 21:29

[range]


range 라는 것은 파이썬에서 연속된 숫자를 얻기 위해서 사용된다.


r = range(10)
print(r[0], r[1], r[-1])

r 의 타입은 range 이고 인덱스를 통해서 접근이 가능하다.


range(10) 이르는 뜻은 0~9까지 숫자를 가지고 있다는 뜻이다.


r = range(5, 10)
print(r[0], r[1], r[-1])

range(5, 10) 이라고 하면 5는 start 가 되서 포함된다.


즉 5부터 라는 뜻이고 10은 stop 이라서 포함이 안되고 9 까지 이다.


r = range(1, 10, 2)
print(r[0], r[1], r[-1])

이번에는 range 의 인자가 3개가 되었다. 


첫번째 부터 start, stop, step 인데 step 은 숫자의 간격이 몇인가를 나타낸다!




[for]


어떤 작업을 할때 반복적으로 해야 하는 경우가 있다.


그렇다고 이것을 전부 일일히 하드코딩 할 수는 없다.


ns = []
ns.append(0)
ns.append(1)
ns.append(2)
ns.append(3)
ns.append(4)


이것을 보고 어떤 생각이 드는가?


유저가 백만명이면 코드에 백만개를 다 써줘야 할까?


그렇지 않다. 규칙이 있다면 반복문을 사용해서 간단히 처리 할 수 있다.


위의 코드에서 규칙을 찾아보자


ns.append 는 모두 같고 추가되는 숫자만 1씩 증가한다.


그럼 저 부분만 변수로 바꾸고 그것을 1씩 증가 시키면 되지 않을까?


ns = []
for n in range(5):
ns.append(n)

코드를 살펴보자


for 문은 위와 같다. in 뒤에 range(5) 는 0~4 숫자를 생성한다.


그것을 0부터 n 에 하나씩 복사한다. 


그래서 ns.append(n) 코드는 총 5번이 실행되고 n 의 값은 순서대로 0, 1, 2, 3, 4 가 되게 된다.



in 뒤에는 리스트나 문자열, 튜플은 물론 이고 iterable, iterarot, generator 등 반복가능한 타입이 올수 있다.



ns = []
"""append"""
for n in range(5):
ns.append(n)
"""modify"""
for i in range(5):
ns[i] = -1
"""print"""
for i in range(5):
print(ns[i])


for 문을 이용해서 리스트를 추가, 수정, 출력을 해보자


append 는 문제가 딱히 없어 보인다.


하지만 modify, print 부분은 위험 요소를 가지고 있다.


modify 에는 5개의 요소를 가진 리스트만 수정할 수 있게 되어있다.


range(5) 를 통해서 인덱스를 0~4 까지 접근할 수 있기 때문이다.


하지만 ns 리스트가 중간에 길이가 변경되면 index out of range 라는 에러가 발생할 것이다.


리스트에 없는 요소를 접근할 때 발생하는 메세지다.


이렇게 코드에 변경되지 않는 값을 써주는 것을 하드코딩이라고 하는데 코드를 직접 수정해야 하고


유연하지 못한 치명적인 문제를 가지고 있다.


리스트의 길이(요소의 개수)가 바뀔때 마다 코드를 수정해야 할까?


그렇다면 어떻게 해야 할까?


for 문을 진입할때 ns 의 길이를 구해야 한다. 다행히 파이썬에는 리스트의 길이를 구하는 함수가 있다.


len() 함수를 통해 길이를 구해서 하면


"""modify"""
for i in range(len(ns)):
ns[i] = -1

이렇게 하면 위에 ns 리스트의 길이가 어떻게 변경되던지 for 문 진입시에 ns 의 길이를 알 수 있다.


하지만 이것도 권장되는 부분은 코드는 아니다


range, len 두개를 써줘야 하면  중간 실수 할 수도 있고 코드도 간결하지 못하다.


"""modify"""
for i, n in enumerate(ns):
ns[i] = -1


enumerate 함수가 이런 문제를 해결해 준다.


enumerate 는 열거자 라고도 하는데 인자값으로 리스트를 넣으면 리스트의 처음 인덱스 와 해당 인덱스의 값을


반환한다.


그러면 인덱스와 값의 미스매치가 날수 도 없고 코드도 안전해진다.


"""print"""
for i in range(5):
print(ns[i])


리스트의 요소를 하나씩 출력하는 부분에서는 위와 같이 할수있다.


하지만 이렇게 인덱스를 굳이 접근해서 할 필요는 없다.


"""print"""
for _, n in enumerate(ns):
print(n)

이렇게 enumerate 를 이용해서 해도 좋다.


_ 는 인덱스를 사용하지 않기 때문에 관례상 _ 를 해주면 된다.


"""print"""
for n in ns:
print(n)

단순 출력 이라면 이게 제일 간결하다.



"""modify"""
for n in ns:
n = -1

이렇게 리스트의 요소를 수정하면 어떻게 될까?


수정할 수 없다.


n 은 복사본이고 ns 와는 상관이 없다.


ns 를 변경하기 위해서는 ns[i] 로 인덱스로 접근을 해야 한다.


그리고 n 은 for 문에서 반복 아래 코드가 반복될때 마다 계속 새로운 값으로 갱신되기 때문에


변경하는게 의미가 없다.











'python lecture > basic' 카테고리의 다른 글

[edu] 재귀함수 한도 설정  (0) 2019.03.20
[edu] pass, continue (제어흐름)  (0) 2019.03.07
[edu] attribute (속성)  (0) 2019.02.26
[edu] logging (로깅)  (0) 2019.02.25
[edu] duck typing(덕 타이핑)  (0) 2019.02.25
댓글