시작은 귀차니즘

조원들과 CodeUp의 Python 기초 100제를 풀기로 했었기에 문제를 풀고 있는 중에 정수를 연속으로 입력받아 처리하는 부분이 아래와 같이 길어지고 있었다.

a, b = input().split()

a = int(a)
b = int(b)
...

split() 함수도 있었고 2개 까지는 괜찮았으나, 3개를 입력받으라는 문제가 나오는 순간 나의 귀차니즘이 발동 되어 구글링을 시작했다. 다행히 아래와 같은 방법으로 int() 함수를 처리하여 1줄로 입력을 받아 낼 수 있었다.

num = list(map(int, input().split()))

하지만, split()에서 생성된 리스트의 각 값들에게 int() 함수를 적용하기 위해 map() 함수를 사용 했다는 것은 이해가 되었으나, list() 함수를 한 번 더 써야 하는 이유가 궁금해 졌다.

map() 함수

map() 함수에 대하여 더 자세히 알아보기 위해 python 에서 아래와 같이 테스트 해 보았다. (백문이 불여 일타)

>>> '1 2'.split()
['1', '2']
>>> map(int, '1 2'.split())
<map object at 0x0000017B8DBCAB30>

응? split()의 결과는 리스트 이지만, map() 함수의 결과는 map object로 나왔다. python.org 에서 map() 함수에 대해 알아보았다.

map(function, iterable, ...)
Return an iterator that applies function to every item of iterable, yielding the results.

첫번째 인자는 내 예상대로 function이지만, 두번째 인자는 iterable을 받고 결과는 map object가 아니라 iterator 였다. iterable과 iterator도 비슷해 보이지만 미묘하게 다른 것 같았다.

iterable 이란?

문서에 보면 아래와 같이 나와 있다.

An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an __iter__() method or with a __getitem__() method that implements Sequence semantics.

"한 번에 하나씩 멤버를 반환할 수 있는 개체" 라고 하는데 모든 sequence 타입(리스트, 문자열, 튜플)과 non-sequence type인 dict, file obejct나 __iter__() method 나 __getitem__() method 를 쓸 수 있는 Class까지 광범위 하다.

iterator 란?

An object representing a stream of data. Repeated calls to the iterator’s __next__() method (or passing it to the built-in function next()) return successive items in the stream.

"데이터 스트림을 나타내는 객체" __next__() method 로 item을 return 할 수 있는 객체를 모두 말하는 것 같다.

map object

그런데 나는 위에서 map() 함수의 결과물로 map object를 얻었다. map object는 무엇인가? python.org에서 찾기는 어려웠고 나와 같은 궁금증을 가진 사람의 블로그에서 힌트를 얻었다. help() 명령으로 map에 대해 알수 있었다. 아래와 같이 __iter()__ method를 가지므로 iterator 이다.

>>> help(map)
Help on class map in module builtins:

class map(object)
 |  map(func, *iterables) --> map object
 |
 |  Make an iterator that computes the function using arguments from
 |  each of the iterables.  Stops when the shortest iterable is exhausted.
 |
 |  Methods defined here:
 |
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |
 |  __iter__(self, /)
 |      Implement iter(self).
 |
 |  __next__(self, /)
 |      Implement next(self).
 |
 |  __reduce__(...)
 |      Return state information for pickling.
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.

iterator를 활용하기 위한 list()

위의 map object는 iterator 객체이므로 이를 쉽게 활용하기 위해 list()를 이용하여 리스트로 만들었던 것이다.

보너스. 지능형 리스트

help() 함수를 소개한 블로그를 살펴보니 지능형 리스트에 대한 이야기가 있다. 위에 map()을 이용한 코드를 아래와 같이 고칠 수도 있겠다.

num = [int(i) for i in input().split()]

뭐가 더 나은지는 읽으시는 분들의 판단에 맞긴다.

레퍼런스

profile
다시 도약하려 노력해보자

0개의 댓글