반복문과 조건문을 사용하는 것보다 간단한 방법으로 원하는 데이터를 생성하는 방법을 알아보자.
리스트 컴프리헨션
리스트를 만들 때 아이템들을 하나하나 나열하는 대신 아이템이 될 수 있는 조건을 적어주면 좀 더 효율적으로 리스트를 작성할 수 있다.
기본적인 사용법은 대괄호 사이에 아이템의 조건을 의미하는 표현식을 적어주면 되는데 반복문 중에서 for를 사용해서 리스트를 작성하면 된다.
원소나열 | 조건제시 |
---|---|
[1, 2, 3, 4] |
[x for x in range(1, 5)] |
[1, 4, 9, 16] |
[x**2 for x in range(1, 5)] |
[101, 102, 103, 104] |
[x+100 for x in range(1, 5)] |
여기에 컴프리헨션(comprehension) 이란 용어는 수학의 집합론에서 유래되었는데 집합을 정의할 때 원소들을 하나하나 나열하는 원소 나열 법과 달리 원소가 될 수 있는 조건을 제시한다는 점에서 조건 제시법으로 부른다.
먼저 리스트를 만들 때 for문을 사용하는 경우부터 보자.
# 반복문을 사용할 경우
my_list = []
for i in range(1, 11):
i = i ** 2
my_list.append(i)
my_list
리스트 컴프리헨션을 사용하면 훨씬 간결하게 적을 수 있다.
# 리스트 컴프리헨션을 사용할 경우
my_list = [x ** 2 for x in range(1, 11)]
my_list
일반적인 for문 사용할 때와 마찬가지로 range() 대신에 다양한 이 트러블을 사용할 수 있다.
range 자리에 리스트를 사용하는 경우
my_list = [x ** 2 for x in [1, 2, 3, 4]]
my_list
range 자리에 튜플을 사용하는 경우
my_list = [x ** 2 for x in (1, 2, 3, 4)]
my_list
range 자리에 집합을 사용하는 경우
my_list = [x ** 2 for x in {1, 2, 3, 4}]
my_list
range 자리에 딕셔너리를 사용하는 경우
my_list = [x ** 2 for x in ({"A": 1, "B": 2, "C": 3, "D": 4}.values())]
my_list
이터러블 자리에 리스트 컴프리헨션을 사용할 수도 있다.
my_list = [x ** 2 for x in [x ** 2 for x in range(11)]]
my_list
이것을 for 루프를 통해 작성할 수도 있는데 좀 더 번거롭다.
my_list_1 = []
my_list_2 = []
for i in range(11):
my_list_1.append(i ** 2)
for i in my_list_1:
my_list_2.append(i ** 2)
my_list_2
조건문과 함께 사용할 수도 있다.
range 대신에 다양한 리터 러블을 사용할 수 있는데 리터 러블의 아이템 중 어떤 특정한 조건을 만족하는 것들을 가져오고 싶을 때 사용하면 편리할 것 같다.
even_number_list = [x for x in range(11) if x % 2 == 0]
even_number_list
두 리스트의 조합도 2중 for문을 사용하는 것보다 훨씬 편하게 만들 수 있다.
combinations = []
for i in [1, 2, 3]:
for j in ("X", "Y", "Z"):
combinations.append((i, j))
print(combinations)
pair = [(x, y) for x in [1, 2, 3] for y in ["X", "Y", "Z"]]
print(pair)
pair = [(x, y) for y in ["X", "Y", "Z"] for x in [1, 2, 3]]
print(pair)
조건을 걸어줄 수도 있다. 1 이상 6 이하의 정수 두 개를 더해서 6이 되는 모든 조합을 찾아준다. 경우의 수 시간에 사용하면 좋을 것 같다.
[(x, y) for x in range(1, 7) for y in range(1, 7) if x + y == 6]
for x in range(1, 7):
for y in range(1, 7):
if x + y == 6:
print((x, y), end=" ")
조건을 중간에 넣을 수도 있다.
[(x, y) for x in range(1, 7) if x > 3 for y in range(1, 7) if x + y == 6]
반복문을 사용하면 조금 더 번거롭다.
my_list = []
for x in range(1, 7):
if x > 3 :
for y in range(1, 7):
if x + y == 6:
my_list.append((x, y))
my_list
튜플을 만들 때는 괄호가 꼭 필요하다.
[(x, x ** 2) for x in range(1, 6)]
[x, x**2 for x in range(6)]
Input In [1]
[x, x**2 for x in range(6)]
^
SyntaxError: invalid syntax
오류가 발생하는 것을 확인할 수 있다.
함수나 메써드와 함께 사용할 수도 있다.
list_1 = [-1, -2, -3, 0, 5, 6, 7]
[abs(x) for x in list_1 if x < 0]
my_fruits = ['apple', 'watermelon', 'grape']
[x.upper() for x in my_fruits]
2중으로 중첩된 리스트를 중첩이 없는 리스트로 바꾸는 데에 사용할 수도 있다.
my_list = [[1,2,3], [4,5,6], [7,8,9]]
new_list = []
for x in my_list:
for y in x:
new_list.append(y)
new_list
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[num for new_list in my_list for num in new_list]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
조건 나열 법으로 집합을 만들 수도 있다.
# Set comprehension
{e ** 3 for e in [1, 2, 3]}
사전도 만들 수 있고 조건을 줄 수도 있다.
# Dict comprehension
{key:value for key, value in enumerate('python')}
{key:value for key, value in enumerate('python') if value in 'pto'}
튜플을 만들 때는 자료형을 적어줘야 한다.
tuple(e ** 3 for e in [1, 2, 3])
a = (e ** 3 for e in [1, 2, 3])
a
type(a)
type(x**2 for x in [1, 2, 3])
문제
주어진 섭씨온도(Celsius)의 리스트를 화씨(Fahrenheit) 온도의 리스트로 변경
$화씨온도 = 섭씨온도 \times {9}/{5} + 32$
예상 결과[32.0, 50.0, 77.0, 86.9]
celsius = [0, 10, 25, 30.5]
1부터 10까지의 정수 중에서 짝수의 제곱만 리스트로 만들기
예상 결과[4, 16, 36, 64, 100]
주어진 문자열의 리스트에서 소문자 a가 들어 있는 단어들만 모두 대문자로 바꿔서 리스트를 만들기
예상 결과['BANANA', 'CRASH', 'MATHEMATICS']
my_list = ['hello', 'Apple', 'banana', 'Cherry', 'crash', 'mathematics']
전치 행렬
주어진 중첩 리스트를 [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
로 변경
# numpy를 사용하여 전치행렬을 이용할 수 있으나 이 경우 자료형이 달라잠.
import numpy as np
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
matrix = np.array(matrix)
print([element for element in matrix.T])
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
# 위의 결과와 비교하여 알아둘 것
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
[element[i] for element in matrix for i in range(4)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
자릿수 합치기
주어진 자연수의 모든 자릿수의 숫자들을 계속 합쳐서 마지막으로 숫자가 하나만 남을 때까지 반복
예전에 이름의 획순으로 숫자를 세어하던 놀이와 비슷함.
예를 들어서 입력받은 숫자가 1357이라면
1357
16
7
이 됨. 이때 1 + 3 + 5 + 7 = 16이고
1 + 6 = 7
힌트
- 숫자를 문자열로 바꾼다. : 1356 -> "1357"
- 리스트 컴프리헨션을 이용해서 문자열을 정수의 리스트로 바꾼다. : [1, 3, 5, 7]
- 각 원소들을 더하고 다시 문자열로 바꾼다. : "16"
num = 1357
[int(num) for num in str(num)]
[1, 3, 5, 7]
sum([int(num) for num in str(num)])
16
num = 1357
while len(str(num)) > 1:
else:
print(num)
1357
16
7
숫자에 천 단위로 컴마 넣기
숫자를 입력받아서 천 단위로 컴마가 들어간 문자열로 바꾸기.
입력 | 출력 |
---|---|
12 | "12" |
1234 | "1,234" |
1234567 | "1,234,567" |
힌트join()
은 문자열의 리스트를 합칠 때 사이사이에 원하는 문자를 넣어줌.
my_list = ["1", "234", "567"]
"/".join(my_list)
'1|234|567'
힌트
- 입력받은 숫자를 문자열로 바꾸고 뒤집는다: 12345 -> "54321"
- 리스트 컴프리헨션을 이용해서 3자리씩 잘라진 문자열의 리스트로 변경: ["543", "21"]
join()
을 이용해서 사이에 컴마를 넣고 합친다.: "543,21"- 다시 뒤집는다.: "12,345"
input_number = 1234567
str_input_number = str(input_number)[::-1]
str_input_number
'7654321'
[str_input_number[i] for i in range(0, 7, 2)]
['7', '5', '3', '1']
input_number = 1234567
'765,432,1'
input_number = 1234567
'1,234,567'
'수학과 코딩' 카테고리의 다른 글
파이썬 리스트 컴프리헨션 사용법 정리 (0) | 2022.08.09 |
---|---|
파이썬 랜덤(random) 사용법 정리(randrange, randint, random.choice 등) (0) | 2022.08.06 |
python 난수(random, range, int, choice)등 정리 및 문제 (0) | 2022.08.06 |
윤년찾기(leap year) 파이썬(python) 날짜와 시간(date and time) (0) | 2022.08.04 |
Python 평균(Mean), 회문(Palindrome)검사, 플로이드 삼각형 (0) | 2022.08.04 |
댓글