[Python101] Iterable (2) – 리스트 – 2

오늘은 리스트의 다른 활용을 살펴보는 두 번째 시간이다. 지난 강좌 글에서 이번에는 리스트와 문자열을 어떻게 변환하는지 살펴보겠다고 했고, 또 지능형 리스트에 대해서도 알아보기로 했다.

문자열과 리스트

문자열을 리스트로 처리하는 방법은 특히 ‘저장된 데이터들’을 처리하기에 편리하다. 즉 어떤 일련의 데이터를 리스트로 다루다가 이를 파일에 저장할 때는 문자열로 기록한다음, 다시 꺼내서 사용할 때는 다시 리스트로 분리하여 사용할 수 있는 것이다.

문자열을 리스트로, 혹은 그 반대로 사용하는 변환하는 방법은 다음과 같은 것들이 있다.

  • 문자열을 한 글자, 한글자로 쪼개어 리스트로 만든다 : list() 함수
  • 문자열속에 특정한 구분자를 통해 여러개의 문자열로 나누어 리스트로 만든다. : split() 메소드
  • 리스트의 원소들을 문자열로 바꾸어 특정한 구분자를 끼워넣어 결합한다. : join() 메소드

대화형 쉘을 실행하고 다음 명령들을 입력해보자.

>>> a = 'copyright'
>>> b = 'It is not safe to modify the sequence being iterated over in loop."
>>> c = range(0, 50, 3)

>>> a
#--> 'copyright'
>>> la = list(a)
>>> la
#--> ['c','o','p','y','r','i','g','h','t']

>>> lb = b.split('\s')
>>> lb
#--> ['It', 'is', 'not', 'safe', 'to', 'modify', 'the', 'sequence', 'being', 'iterated', 'over', 'in', 'loop.']

>>> d = ','.join(lb)
>>> d
#--> 'It,is,not,safe,to,modify,the,sequence,being,iterated,over,in,loop.'

split()은 문자열의 메소드이다. 이는 인수로 받은 글자를 기준으로 문자열을 쪼개어 리스트로 만들어준다. 즉 위의 예제에서는 긴 문장에 대해 공백문자를 기준으로 분리한다고 했다. 그리고 그 결과는 lb에 대입하였고, lb를 통해서 만들어진 리스트를 확인할 수 있었다.

거꾸로 join() 역시 문자열의 메소드인데, 구분자로 사용할 글자를 주고 이 글자의 join 메소드를 사용하면 리스트의 원소를 다시 결합할 수 있다. d를 통해 이를 확인할 수 있었다.

지능형 리스트

위의 예제에서 c는 왜 만들었을까? 지금까지 보았던 range() 함수의 사용과는 조금 색다른데가 있다. 즉 시작값, 끝값 그 뒤에 뭔가 추가적인 인수를 더 썼다. 궁금증은 help를 통해 알아보면 된다. help(range) 라고 하면 아래와 같이 설명을 볼 수 있는데,

Help on built-in function range in module __builtin__:

range(...)
    range([start,] stop[, step]) -> list of integers

    Return a list containing an arithmetic progression of integers.
    range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
    When step is given, it specifies the increment (or decrement).
    For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
    These are exactly the valid indices for a list of 4 elements.

range( [start], stop [, step]) 이라고 되어 있다. 즉 시작값과 끝값, 그리고 그 다음은 “간격”이다. 그리고 중요한 것 하나. 이렇게 함수 도움말에서 인자에 [대괄호]로 묶은 부분이 있다면 이 값은 필수가 아니라는 점이다. range() 함수에서는 오직 stop 만이 필수로 들어가는 값이다.

즉 함수가 인자로 받는 인수의 개수가 동적으로 바뀔 수 있다는 점인데, 이는 다른 언어에서는 허용하지 않는 경우가 많다. 이는 파이썬의 유연성을 높이는 굉장히 멋진 기능이다!

어쨌든 위의 예제에서 c는 0에서 시작하여 50보다 작은 3의 배수들을 모두 모아보았다. 이 들을 그냥 0, 1, 2, 3…  이런 식으로 다시 만들 수 있을까? 다음과 같은 코드를 생각해 볼 수 있다.

f = []
for x in c:
   f.append(x/3)

즉 c의 각 원소 x에 대해서 3으로 나눈 다음 그 결과를 f에 하나씩 밀어넣으면 된다. f 값을 확인해보면 결과를 확인해볼 수 있다.

그런데 이런 처리는 의외로 파이썬에서 종종 쓰인다. 그래서 파이썬은 ‘지능형 리스트’라는 걸 사용하는데 다음과 같이 사용한다.

[ {변수명}을 사용하는 서식 for {변수명} in {리스트명} ]

즉 f는 위의 코드가 아닌 단 한줄의 코드로 정리할 수 있다.

f = [num/3 for num in c]

지능형 리스트는 자주 쓰이지 않는 리스트 변환 작업을 따로 함수로 빼지 않고 다른 구문 내에서 간단히 처리하고자 할 때 쓰인다. 사실 지능형 리스트의 활용 방법은 조금 더 있지만, 그건 나중에 필요할 때 다시 언급하기로 하고, 여기서는 간단히 이런게 있다는 것만 설명하고 넘어가도록 하자.