반복: 어떤 조건이 성립하는 동안 반복해서 처리하는 구조를 반복 구조(repetition structure)라 하고 Loop라고도 한다.
loop : while과 for
while
조건식이 참일 동안 명령문이 반복되다가 false가 뜨는 순간 반복 종료
실행하기 전에 반복을 계속할 것인지 판단한다. (사전 판단 반복 구조)
while ( condition) {
statements;
//body of the loop
}
for
for(initialization; condition; iteration){
//body of the 'for' loop
}
while vs for
While | for | |
언제 사용하나? | 반복 횟수(umber of iterations)가 정해지지 않을 때 | 반복의 횟수를 이미 알고 있을 때 |
조건이 없다면? | compile time error를 리턴한다. | 무한반복한다. |
초기화는 언제? | 매 반복시에 반복한다 | 루프 전에 한 번 하고 반복 하지 않음 |
초기화를 어디서? | 루프 body 어디에서든 할 수 있다 | 루프의 시작에서 실행됨 |
함수가 사용되나? | 그런 기능은 없다. | rnage / xrange 함수가 반복시 사용됨 |
빠르기 비교 | for 루프보다는 상대적으로 느리다 | while 루프보다는 빠르다 |
출처: https://www.tutorialspoint.com/difference-between-for-loop-and-while-loop-in-python
[한걸음 더] python 의 Iterable, Iterator
차후 추가: yield, generator
Iterable
반복 가능하다는 뜻.
- Iterable 객체: 문자열, 리스트, 튜플, 집합 등의 자료형 객체는 모두 이터러블(반복 가능)하다.
- list, dict, set, str, bytes, tuple, range..
- 이터러블한 객체인지 어떻게 판별할까?
- 방법1: collection.abc 모듈을 import해서 Iterable 의 instance를 가지고 있는지 아닌지로 판별한다. (isinstance를 사용하여 True를 반환하면 그 객체는 iterable하다.)
- Python 3.10부터 어떤 클래스가 특정 인터페이스를 제공하는지 아닌지 테스트하는 기능인 abstract base classes가 collection에서 collection.abc로 분리되었고, Iterable 매서드도 함께 분리되어 딸려나왔다. collection.abc 공식문서
- 방법2: dir 로 객체 내부를 살펴보면 __iter__ 라는 매직 매서드가 존재함을 알 수 있다.
- hasattr 함수를 사용하기
- 방법1: collection.abc 모듈을 import해서 Iterable 의 instance를 가지고 있는지 아닌지로 판별한다. (isinstance를 사용하여 True를 반환하면 그 객체는 iterable하다.)
타입에 대한 이야기
Sequence Type : list, tuple, range, str … : 값이 연속적으로 이어진 자료형. sequence 객체는 iterable하다.
iterable과 sequence에 대한 stackoverflow의 질문
iterators : 이터레이터
값을 순회하여 꺼낼 수 있는 객체로, 데이터의 나열을 표현하는 객체.
이터러블한 객체를 내장 함수 iter의 인수로 전달하거나, 객체의 __iter__() 를 사용하면 그 객체에 대한 이터레이터를 반환한다. (iterator 객체들은 iterator로 사용될 때 iter() method를 갖는다.)
mylist=[1,2,3]
print(mylist.__iter__()) #<list_iterator object at 0x00000181ABE7A530>
print(iter(mylist)) #<list_iterator object at 0x00000181ABE7A530>
create an Iterator (class)
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
이터레이터는 어떻게 사용할까?
- 이터레이터 객체의 __next__() 함수를 호출하여 사용
it = iter(range(3)) print(it) #<range_iterator object at 0x0000017E8ED6BDD0> #이터레이터 객체의 __next__함수를 호출하여 사용 print(it.__next__()) #0 print(it.__next__()) #1 print(it.__next__()) #2
- 내장 함수인 next()함수에 이터레이터를 전달
it = iter(range(3)) print(it) #<range_iterator object at 0x0000017E8ED6BDD0> #내장 함수인 next()함수에 이터레이터를 전달 print(next(it)) #0 print(next(it)) #1 print(next(it)) #2
- 꺼낼 원소가 더 없다면?: StopIteration 예외 발생
Traceback (most recent call last):
File "iterators.py", line 7, in <module>
print(it.__next__())
^^^^^^^^^^^^^
StopIteration
- StopIteration and class
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
반복문과 이터레이터는 그래서 무슨 상관이 있나?
The for statement : The [for](<https://docs.python.org/3/reference/compound_stmts.html#for>) statement is used to iterate over the elements of a sequence (such as a string, tuple or list) or other iterable object:
for_stmt ::= "for" target_list "in" starred_list ":" suite
["else" ":" suite]
The starred_list expression is evaluated once; it should yield an iterable object. An iterator is created for that iterable.
파이썬의 for문의 header는 전통적인 구조( c처럼 for(i=0;i<10;i++)) 가 아니라 독특한 구조를 갖고 있다. 이게 가능한 이유를 공식문서는 iterator를 사용하기 때문에 이렇게 쓸 수 있다고 한다.
이렇게 쓰기 위해서는 조건이 있다. in뒤에 놓이는 starrted_list가 반드시 iterable 객체를 yield 할 수 있어야 한다. 왜냐하면 이 리스트가 시작시 한 번 사용(평가)될 때 iterable한 객체의 iterator(반복자)를 반환(생성)하고, 그것이 자동으로 assignment의 규칙의 target list에 배치되어 반복문이 돌아가기 때문이다.
즉 한마디로 요약해서 python의 독특한 형식의 for문은 iterator를 사용하여 이렇게 쓰일 수 있다고 생각하면 될 것 같다.
차후 조금 더 공부하고 추가할 내용
Generator
yield
관련 내장 함수
반복이 필요한 알고리즘을 짤 때 많이 쓰이는 내장 함수로 추정되는 함수 리스트. (주관적)
- enumerate(iterable, start=0)
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
list(zip(range(3), ['fee', 'fi', 'fo', 'fum']))
[(0, 'fee'), (1, 'fi'), (2, 'fo')]
'공부기록 > Algorithm' 카테고리의 다른 글
[TIL][TUE] 병합정렬/퀵정렬 (1) | 2023.10.17 |
---|---|
[TIL][Mon] 정렬 (2) | 2023.10.16 |
[TIL][W2/Mon] 복잡도, Big O notation (0) | 2023.10.16 |
[TIL][W1/Sun] 소수찾기 (0) | 2023.10.16 |
[TIL][W1/Sat] 배열/문자열 (0) | 2023.10.14 |