리스트 컴프리헨션(list comprehension): 리스트 안에 식, for 반복문, if 조건문 등을 지정하여 리스트를 생성하는 것. 리스트 내포, 리스트 내장, 리스트 축약, 리스트 해석 등으로 쓴다.
- [식 for 변수 in 리스트]
- list(식 for 변수 in 리스트)
>>> a = [i for i in range(0, 10, 2)] # 0부터 9까지 2 간격으로 숫자 생성
>>> a
[0, 2, 4, 6, 8]
>>> b = list(i for i in range(1, 10, 2))
>>> b
[1, 3, 5, 7, 9]
리스트 표현식은 뒤에서 앞으로 읽으면 간단하다. 즉, range(0, 10, 2)으로 0부터 2간격으로 9까지 생성하여 변수 i에 숫자를 꺼내고, 최종적으로 i를 이용하여 리스트를 만든다는 뜻이다.
식 부분에서 i를 다른 값과 연산하면 각 연산의 결과를 리스트로 생성할 수 있다.
>>> c = [i + 10 for i in range(10)] # 0부터 9까지 숫자를 생성하면서 값에 10을 더하여 리스트 생성
>>> c
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> d = list(i * 3 for i in range(10))
>>> d
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
- [식 for 변수 in 리스트] : 파이썬 다운 코드(이 방식을 사용하는 것이 좋음)
- list(식 for 변수 in 리스트): C 언어 스타일(이렇게 만들 수 있다는 정도만 알면 된다)
- [식 for 변수 in 리스트 if 조건식]
- list(식 for 변수 in 리스트 if 조건식)
>>> a = [i for i in range(20, 30) if i % 3 == 0] # 20 ~ 29 숫자 중 3의 배수인 숫자로 리스트 생성
>>> a
[21, 24, 27]
숫자 10개(20 ~ 30)를 생성하고 3의 배수만 뽑아낸 후에, 숫자를 하나씩 꺼내고 i로 리스트를 생성한다.
>>> b = [i * 2 for i in range(10) if i % 2 == 0]
>>> b
[0, 4, 8, 12, 16]
[식 for 변수1 in 리스트1 if 조건식1 for 변수2 in 리스트2 if 조건식2 ... for 변수n in 리스트n if 조건식n]
list(식 for 변수1 in 리스트1 in 리스트1 if 조건식1 for 변수2 in 리스트2 if 조건식2 ... for 변수n in 리스트n if 조건식n)
>>> a = [i * j for j in range(2, 10) for i in range(1, 10)]
>>> a
[2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15, 18, 21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36, 5, 10, 15, 20, 25, 30, 35, 40, 45, 6, 12, 18, 24, 30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56, 63, 8, 16, 24, 32, 40, 48, 56, 64, 72, 9, 18, 27, 36, 45, 54, 63, 72, 81]
>>> b = list(i * j for j in range(2, 10) for i in range(1, 10))
>>> b
[2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15, 18, 21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36, 5, 10, 15, 20, 25, 30, 35, 40, 45, 6, 12, 18, 24, 30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56, 63, 8, 16, 24, 32, 40, 48, 56, 64, 72, 9, 18, 27, 36, 45, 54, 63, 72, 81]
코드를 한 줄로 입력하지않고, 여러 줄로 입력해도 된다.
a = [i * j for j in range(2, 10)
for i in range(1, 10)]
들여쓰기는 해도 되고 안해도 되지만, 가독성을 위해 들여쓰기를 하는 것이 좋다.
리스트 표현식에 for가 여러 개일 때 처리 순서는 뒤에서 앞으로 순이다.
a = [i * j for j in range(2, 10) for i in range(1, 10)]
1. for i in range(1, 10) 숫자 9개를 생성하고
2. for j in range(2, 10) 숫자 8개를 생성하고
3. i * j로 리스트가 생성도니다.
map: 리스트의 요소를 지정된 함수로 처리해주는 함수(map은 원본 리스트를 변경하지 않고 새 리스트를 생성한다.)
- list(map(함수, 리스트))
- tuple(map(함수, 튜플))
for 반복문을 사용해서 실수가 저장된 리스트의 모든 요소를 정수로 변환해보면
>>> a = [1.2, 3.5, 2.6, 4.5]
>>> for i in range(len(a)):
a[i] = int(a[i])
>>> a
[1, 3, 2, 4]
for에 range(len(a))를 사용해서 인덱스를 가죠오고, 가져온 인덱스로 요소 하나 하나에 접근한 뒤 int로 변환해서 다시 저장을 하니, 번거롭다. 이때, map을 사용하면 편리하다.
>>> a = [1.2, 3.5, 2.6, 4.5]
>>> a = list(map(int, a))
>>> a
[1, 3, 2, 4]
map에는 리스트뿐만 아니라 모든 반복 가능한 객체를 넣을 수 있다. range를 사용해서 0부터 9까지 짝수를 만든 뒤, 문자열로 변환해보자.
>>> a = list(map(str, range(0, 10, 2)))
>>> a
['0', '2', '4', '6', '8']
input().split()으로 값을 여러 개 입력받고 정수, 실수로 변환할 때도 map을 사용했는데, 이것은 사실 input().split()의 결과가 문자열 리스트라서 map을 사용할 수 있었던 것이었다.
아래와 같이 input().split()을 사용한 뒤에 변수 한 개에 저장해보면 리스트인지 확인할 수 있다.
>>> a = input().split()
10 20
>>> a
['10', '20']
map을 사용해서 정수로 변환해보자
>>> a = map(int, input().split())
1 2
>>> a
<map object at 0x03F8FD18> # 맵 객체(map object)가 만들어짐
>>> list(a) # 안에 들어있는 값을 보기위해서 리스트로 출력
[1, 2]
이 리스트 [1, 2]를 변수 두 개에 저장하면 지금까지 사용한 a, b = map(int, input().split())와 같은 동작이 된다.
>>> a, b = [1, 2]
>>> a
1
>>> b
2
a, b = map(int, input().split())을 풀어서 써보면...
x = input().split() # input().split()의 결과는 문자열 리스트
m = map(int, x) # 리스트의 요소를 int로 변환, 결과는 맵 객체
a, b = m # 맵 객체는 변수 여러 개에 저장할 수 있음
튜플은 리스트와는 다르게 내용을 변경할 수 없다. 그래서 요소의 정보를 구하는 메서드만 사용할 수 있다.
index(값)으로 튜플에서 특정 값의 인덱스를 구한다. 같은 값이 여러 개일 경우에는 처음 찾은 인덱스를 구한다.
>>> a = (50, 32, 1, 24, 3, 32)
>>> a.index(32)
1
count(값)은 튜플에서 특정 값의 개수를 구한다.
>>> a = (10, 10, 10, 10, 5, 1, 2, 10, 10, 10)
>>> a.count(10)
7
for 반복문으로 요소를 출력하는 방법은 리스트와 같다
>>> a = (20, 10, 43, 21, 19)
>>> for i in a:
print(i, end=' ')
20 10 43 21 19
- tuple(식 for 변수 in 리스트 if 조건식)
>>> a = tuple(i for i in range(10, 20) if i % 2 == 0)
>>> a
(10, 12, 14, 16, 18)
>>>
>>> a = (1.5, 2.4, 3.9, 4.5, 5.2)
>>> a = tuple(map(int, a))
>>> a
(1, 2, 3, 4, 5)
>>> a = (12, 42, 13, 55, 5)
>>> min(a)
5
>>> max(a)
55
>>> sum(a)
127
파이썬에서는 리스트 표현식을 자주 사용하므로 반복 학습해서 정확하게 익히는 것이 좋다.
표준 입력으로 정수 두 개가 입력됩니다(첫 번째 입력 값의 범위는 1~20, 두 번째 입력 값의 범위는 10~30이며 첫 번째 입력 값은 두 번째 입력 값보다 항상 작습니다). 첫 번째 정수부터 두 번째 정수까지를 지수로 하는 3의 거듭제곱 리스트를 출력하는 프로그램을 만드세요(input에서 안내 문자열은 출력하지 않아야 합니다). 단, 리스트의 세 번째 요소와 뒤에서 세 번째 요소는 삭제한 뒤 출력하세요. 출력 결과는 리스트 형태라야 합니다.
start, stop = map(int, input().split())
a = [3 ** i for i in range(start, stop + 1)] # start, stop + 1 첫 번째 입력 값은 두 번째 입력 값보다 항상 작음
del a[2] # a.pop(2)도 가능
del a[-3] # a.pop(-3)도 가능
print(a)
1 10
[3, 9, 81, 243, 729, 2187, 19683, 59049]