import numpy as np
import matplotlib.pyplot as plt
03wk-2: 리스트는 쓰레기인가?
1. 강의영상
2. Imports
3. 리스트는 쓰레기인가?
A. 벡터화연산(브로드캐스팅) 불가능
-
벡터화연산 불가능 (최악의 단점)
= [1,2,3]
lst + 1 lst
TypeError: can only concatenate list (not "int") to list
= np.array([1,2,3])
arr + 1 arr
array([2, 3, 4])
B. bool을 이용한 인덱싱이 불가능
-
True, False 가 포함된 array를 이용한 인덱싱이 불가능하다.
-
넘파이에서 bool을 이용한 인덱싱
= np.array([1,2,3,4,5])
arr >3] arr[arr
array([4, 5])
-
리스트는 불가능
= [1,2,3,4,5]
lst >3] lst[lst
TypeError: '>' not supported between instances of 'list' and 'int'
>3 lst
TypeError: '>' not supported between instances of 'list' and 'int'
C. 넘파이 특화 메소드 사용불가능
-
넘파이 특화 메소드
= np.array([5,4,3,2,1])
arr arr
array([5, 4, 3, 2, 1])
min(), arr.max(), arr.mean(), arr.argmin(), arr.argmax() arr.
(1, 5, 3.0, 4, 0)
arr.sort() arr
array([1, 2, 3, 4, 5])
-
리스트는?
= [5,4,3,2,1]
lst lst
[5, 4, 3, 2, 1]
min(), lst.max(), lst.mean(), lst.argmin(), lst.argmax() lst.
AttributeError: 'list' object has no attribute 'min'
lst.sort() lst
[1, 2, 3, 4, 5]
# 메소드란?
– 자료형에 종속된 특수기술
# 넘파이 특수기술
= np.array([1,2,3])
arr max() # max(arr)로 해석 arr.
3
# ?.max() 이런건 넘파이 특수기술 이니까 ?자리에 리스트일 경우는 실행안됨
= [1,2,3]
lst max() lst.
AttributeError: 'list' object has no attribute 'max'
# 리스트의 특수기술
= [1,2,3]
lst 4) # append(lst,4) 로 해석
lst.append( lst
[1, 2, 3, 4]
# 문자열 특수기술
= 'asdf'
s # capitalize(s) 로 해석 s.capitalize()
'Asdf'
# 문자열 특수기술
= '-'
s = ['x','y','z']
lst # join(s,lst) 로 해석 s.join(lst)
'x-y-z'
join(s,lst)
의 뜻: lst의 각 원소를 모두 “이어서” 하나의 문자열로 만들어라. 단, 원소간의 구분은s
에 저장된 문자열로 하라.
# 문자열 특수기술 응용
''.join(['x','y','z'])
'xyz'
# 문자열 특수기능
= "제 이름은 {} 입니다."
s = "최규빈"
name format(name) # format(s,name) s.
'제 이름은 최규빈 입니다.'
format(s,name)
의 뜻: s라는 문자열의 포맷에{}
자리에 name을 끼워넣어라.
D. 파이썬에서 쓰레기 같은 자료형은 없다.
-
파이썬에는 각 자료형마다 사용할 수 있는 고유기술(=메소드)이나 문법이 있음.
-
내가 생각할 때 리스트는 필요없는 자료형이야 = 난 리스트만 가지고 있는 어떠한 고유특징을 활용하지 못해.
-
파이썬을 잘 하려면 자료형에 따른 고유 특징을 이해하고 활용할 줄 알아야 한다.
- 기본자료형: str, list, tuple, dict, set – 이러한 자료형을 이해하고 기능을 활용해야함
- 모듈: 넘파이배열, 판다스
4. 2024년 수능 – 확통 23
A. 문제파악
-
기존의 문제들과 다르게 numpy를 이용하여 풀기는 어려울 것 같다. 뭔가 기존문제들과 결이 다름
-
그런데 코딩으로 해결가능할 것 같긴 함
B. 슈도알고리즘
1.
편의상 \([x,x,y,y,z]\)를 \([x_1,x_2,y_1,y_2,z]\)와 같이 생각하고 나열한다. (5! = 120 개만큼 경우가 나열되겠지)
2.
중복을 제거한다. 즉 아래는 모두 같은 경우로 생각한다.
- \([x_1,x_2,y_1,y_2,z]\)
- \([x_1,x_2,y_2,y_1,z]\)
- \([x_2,x_1,y_1,y_2,z]\)
- \([x_2,x_1,y_2,y_1,z]\)
C. 예비학습
# 개념1
– 집합이라는 자료형이 있음.
= {1,2,3}
a type(a)
set
그런데 집합은 중복된 원소를 포함하지 않았음 (중학교때 배운듯)
= {1,2,3,3,3}
a a
{1, 2, 3}
#
# 개념2
– 자료형변환을 이용하여 중복된 원소를 제거
아래와 같은 자료형이 있다고 하자.
= [1,2,3,3,3]
lst lst
[1, 2, 3, 3, 3]
중복된 것을 제외하고 싶다면?
list(set(lst)) # 자료형변환
[1, 2, 3]
#
# 개념3
– 고유의 원소 숫자 세기
= [1,2,3,3,3,4,4,5,5,6]
lst lst
[1, 2, 3, 3, 3, 4, 4, 5, 5, 6]
len(set(lst))
6
#
# 개념4
– for문
아래를 출력하고 싶다고 하자.
이효리는 핑클의 멤버이다.
옥주현은 핑클의 멤버이다.
성유리는 핑클의 멤버이다.
이진은 핑클의 멤버이다.
(풀이1) – 단순한 풀이
print("이효리는 핑클의 멤버이다.")
print("옥주현은 핑클의 멤버이다.")
print("성유리는 핑클의 멤버이다.")
print("이진은 핑클의 멤버이다.")
이효리는 핑클의 멤버이다.
옥주현은 핑클의 멤버이다.
성유리는 핑클의 멤버이다.
이진은 핑클의 멤버이다.
(풀이2) – 문자열 특수기능을 이용해볼까?
“{} 핑클의 멤버이다.” 이 공통포맷이므로, 아래와 같이 수행할 수 있겠다.
= ["이효리는","옥주현은","성유리는","이진은"]
lst = 0
i print("{} 핑클의 멤버이다.".format(lst[i]))
= 1
i print("{} 핑클의 멤버이다.".format(lst[i]))
= 2
i print("{} 핑클의 멤버이다.".format(lst[i]))
= 3
i print("{} 핑클의 멤버이다.".format(lst[i]))
이효리는 핑클의 멤버이다.
옥주현은 핑클의 멤버이다.
성유리는 핑클의 멤버이다.
이진은 핑클의 멤버이다.
(풀이3) - for와 문자열 특수기능을 이용해볼까?
= ["이효리는","옥주현은","성유리는","이진은"]
lst for i in [0,1,2,3]:
print("{} 핑클의 멤버이다.".format(lst[i]))
이효리는 핑클의 멤버이다.
옥주현은 핑클의 멤버이다.
성유리는 핑클의 멤버이다.
이진은 핑클의 멤버이다.
(풀이4) - for와 문자열 특수기능을 이용해볼까? (2)
[0,1,2,3]
은 대충 range(4)
와 비슷한 것이므로 아래와 같이 수행할 수도 있겠음.
= ["이효리는","옥주현은","성유리는","이진은"]
lst for i in range(4):
print("{} 핑클의 멤버이다.".format(lst[i]))
이효리는 핑클의 멤버이다.
옥주현은 핑클의 멤버이다.
성유리는 핑클의 멤버이다.
이진은 핑클의 멤버이다.
(풀이5) - for와 문자열 특수기능을 이용해볼까? (3)
아래의 코드는 \(i\) 자리에 [0,1,2,3]
의 원소가 번갈아 대입되며 ??????
가 수행되었음.
= ["이효리는","옥주현은","성유리는","이진은"]
lst for i in [0,1,2,3]:
??????
아래의 코드도 \(i\) 자리에 range(4)
의 원소가 번갈아 대입되며 ??????
가 수행되었다고 해석가능.
= ["이효리는","옥주현은","성유리는","이진은"]
lst for i in range(4):
??????
아래의 코드는 어떻게 실행될까??
= ["이효리는","옥주현은","성유리는","이진은"]
lst for i in lst:
??????
# R과 다른 방식으로 동작하는 for문
= ["이효리는","옥주현은","성유리는","이진은"]
lst for l in lst:
print("{} 핑클의 멤버이다.".format(l))
이효리는 핑클의 멤버이다.
옥주현은 핑클의 멤버이다.
성유리는 핑클의 멤버이다.
이진은 핑클의 멤버이다.
#
# 개념5
– for문을 이용하여 리스트의 원소 추가하기
= [] # lst2 = list() 와 같은결과임
lst2 = ["이효리는","옥주현은","성유리는","이진은"]
lst for l in lst:
"{} 핑클의 멤버이다.".format(l)) lst2.append(
lst2
['이효리는 핑클의 멤버이다.', '옥주현은 핑클의 멤버이다.', '성유리는 핑클의 멤버이다.', '이진은 핑클의 멤버이다.']
그런데 이걸 아래와 같이 해결할 수도 있다.
= ["이효리는","옥주현은","성유리는","이진은"]
lst "{} 핑클의 멤버이다.".format(l) for l in lst] # 리스트컴프리헨션 [
['이효리는 핑클의 멤버이다.', '옥주현은 핑클의 멤버이다.', '성유리는 핑클의 멤버이다.', '이진은 핑클의 멤버이다.']
#
# 개념6
– 리스트컴프리헨션
집합을 표현하는 방법에는 원소나열법과 조건제시법이 있다.
- 원소나열법: \(\{2^0,2^1,2^2,2^3\}\)
- 조건제시법: \(\{2^i: \text{ for } i=0,1,2,3\}\)
이중에서 조건제시법은 아래와 같이 표현할 수 있음.
- \(\{2^i: \text{ for } i \in \{0,1,2,3\}\}\)
여기에서 \(\in\) 은 in
으로 읽으므로, 위의 표기법을 연상하여 파이썬 코드로 바꿔보면
2^i: for i in [0,1,2,3]] [
와 같은 방식으로 리스트의 원소를 표현할 수 있을 것 같다. 위의 코드는 실행되지 않지만 아래의 코드는 실행가능하다.
2**i for i in [0,1,2,3]] [
[1, 2, 4, 8]
2**i for i in range(4)] [
[1, 2, 4, 8]
이를 응용하면
"asdf{}".format(2**i) for i in range(4)] [
['asdf1', 'asdf2', 'asdf4', 'asdf8']
이것을 다시 응용하면
= ["이효리는", "성유리는", "옥주현은", "이진은"]
lst "{} 핑클의 멤버이다.".format(l) for l in lst] [
['이효리는 핑클의 멤버이다.', '성유리는 핑클의 멤버이다.', '옥주현은 핑클의 멤버이다.', '이진은 핑클의 멤버이다.']
#
# 개념7
– 스트링의 인덱싱 (파이썬에서는 스트링을 array로 취급)
= 'asdf'
s s
'asdf'
0] s[
'a'
-1] s[
'f'
2] s[:
'as'
#
# 개념8
– 스트링과 리스트의 변환
= 'asdf'
s s
'asdf'
= list(s)
lst lst
['a', 's', 'd', 'f']
''.join(lst)
'asdf'
# 개념9
– 튜플자료형
= [1,2,3]
lst lst
[1, 2, 3]
= (1,2,3)
tpl tpl
(1, 2, 3)
튜플은 (의미가 명확할때) 괄호를 생략할 수 있음
= 1,2,3
tpl tpl
(1, 2, 3)
튜플은 리스트와 매우 비슷함.
1,2,3] + [4,5] [
[1, 2, 3, 4, 5]
1,2,3) + (4,5) (
(1, 2, 3, 4, 5)
아래도 가능
''.join(['a','b','c'])
'abc'
''.join(('a','b','c'))
'abc'
#
# 개념10
– for를 수행하는 다양한 테크닉
우리가 알고 있는 for
: 리스트 비슷한 것을 만든 뒤, 그 리스트의 원소를 하나씩 뽑아가면서 어떠한 반복구문 “??????” 수행하는 것.
import itertools
for i in itertools.permutations(['a','b','c']):
print(i)
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')
for i in itertools.product(['x','y'],['a','b','c']):
print(i)
('x', 'a')
('x', 'b')
('x', 'c')
('y', 'a')
('y', 'b')
('y', 'c')
#
D. 풀이
아래의 문제를 풀어보자..
(풀이)
len(set([''.join(i) for i in itertools.permutations(['x','x','y','y','z'])]))
30
5. 2024년 수능 – 확통29
A. 문제이해
B. 슈도알고리즘
1
. 아래의 경우를 모두 나열한다.
= 1,1,1,1
a,b,c,d = 1,1,1,2
a,b,c,d
....= 6,6,6,6 a,b,c,d
2
. 조건 \(a \leq c \leq d\) 와 \(b \leq c \leq d\) 를 동시에 만족하는 경우를 센다.
C. 예비학습
# 개념1
– for문과 튜플
= [['최규빈',43052,'M'],['아이유',54321,'F'],['하니',11223,'F']]
lst 0] lst[
['최규빈', 43052, 'M']
아래의 코드가 가능하다.
for [name,student_id,sex] in lst:
print([name,student_id,sex])
# [name,student_id,sex] = ['최규빈', 43052, 'M']
# print([name,student_id,sex])
# [name,student_id,sex] = ['아이유', 54321, 'F']
# print([name,student_id,sex])
# [name,student_id,sex] = ['하니', 11223, 'F']
# print([name,student_id,sex])
['최규빈', 43052, 'M']
['아이유', 54321, 'F']
['하니', 11223, 'F']
리스트를 튜플로 바꾼다면?
for (name,student_id,sex) in lst:
print((name,student_id,sex))
# (name,student_id,sex) = ['최규빈', 43052, 'M']
# print((name,student_id,sex))
# (name,student_id,sex) = ['아이유', 54321, 'F']
# print((name,student_id,sex))
# (name,student_id,sex) = ['하니', 11223, 'F']
# print((name,student_id,sex))
('최규빈', 43052, 'M')
('아이유', 54321, 'F')
('하니', 11223, 'F')
for (name,student_id,sex) in lst:
대신에 for name,student_id,sex in lst:
도 가능
for name,student_id,sex in lst:
print((name,student_id,sex))
# name,student_id,sex = ['최규빈', 43052, 'M']
# print((name,student_id,sex))
# name,student_id,sex = ['아이유', 54321, 'F']
# print((name,student_id,sex))
# name,student_id,sex = ['하니', 11223, 'F']
# print((name,student_id,sex))
('최규빈', 43052, 'M')
('아이유', 54321, 'F')
('하니', 11223, 'F')
아래와 같이 컴프리헨션으로 만들 수도 있음.
for name,student_id,sex in lst] [[name,student_id,sex]
[['최규빈', 43052, 'M'], ['아이유', 54321, 'F'], ['하니', 11223, 'F']]
for name,student_id,sex in lst] [(name,student_id,sex)
[('최규빈', 43052, 'M'), ('아이유', 54321, 'F'), ('하니', 11223, 'F')]
아래는 불가능
for name,student_id,sex in lst] [name,student_id,sex
SyntaxError: did you forget parentheses around the comprehension target? (905514563.py, line 1)
하지만 괄호를 명확하게 쓰기만 하면 만들어짐
for name,student_id,sex in lst] [(name,sex)
[('최규빈', 'M'), ('아이유', 'F'), ('하니', 'F')]
for name,student_id,sex in lst] [(sex,name)
[('M', '최규빈'), ('F', '아이유'), ('F', '하니')]
for name,student_id,sex in lst] [name
['최규빈', '아이유', '하니']
언더스코어(_
)를 사용할 수도 있음.
for name,_,_ in lst] [name
['최규빈', '아이유', '하니']
언더스코어(_
)를 사용시 lst[0]
, lst[1]
등의 원소숫자와 일치하도록 사용해야함
for name,_ in lst] # 이건 또 실행불가능.. [name
ValueError: too many values to unpack (expected 2)
for name, *args in lst] # 이건 실행가능 [name
['최규빈', '아이유', '하니']
# 개념2
– 조건문
아래의 리스트 원소 \(l\) 중에서 조건 \(1 < l \leq 5\)를 만족하는 원소는 모두 몇개인가?
= [1,2,3,4,5,6,7,8,9]
lst lst
[1, 2, 3, 4, 5, 6, 7, 8, 9]
(풀이)
sum([1<l and l<=5 for l in lst])
4
sum([1<l<=5 for l in lst])
4
D. 풀이
(풀이)
= [1,2,3,4,5,6]
lst sum([a<=c<=d and b<=c<=d for a,b,c,d in itertools.product(lst,lst,lst,lst)])
196
6. 2024년 수능 – 19 (다시풀기)
A. 문제파악
B. 예비학습
-
예제: 제곱수중에서 12로 나누어서 떨어지는 수만 원소르 가지는 리스트를 만들고 싶다.
- 제곱수: 1,4,9,16,25,36,…
- 12로 나누어서 떨어지는 수: 36
(복습1)
12 % 4 # % 는 나머지를 계산하는 연산자, 12를 4로 나누었더니 나머지가 0
0
12 % 5 # 12 = 5*2 +2
2
(복습2)
= 3 # a에 2를 대입하라... a
== 2 # a에 들어있는 값이 2이인지 테스트하라.. a
False
== 3 a
True
(풀이1) – 비어있는 리스트를 만들고, for + if 를 사용
= []
lst for i in range(1,101):
if i**2 % 12 == 0: # i^2을 12로 나누어서 나누어 떨어진다면
**2) lst.append(i
lst
[36,
144,
324,
576,
900,
1296,
1764,
2304,
2916,
3600,
4356,
5184,
6084,
7056,
8100,
9216]
(풀이2) - if문이 포함된 리스트 컴프리헨션
**2 for i in range(1,101) if i**2 % 12 ==0] [i
[36,
144,
324,
576,
900,
1296,
1764,
2304,
2916,
3600,
4356,
5184,
6084,
7056,
8100,
9216]
C. 풀이
(풀이)
= list(range(1,16))
x = lambda x: np.sin(np.pi/4*x)
f sum([xi for xi in x if f(2+xi)*f(2-xi)<1/4])
32
7. 컴프리헨션 연습
지금까지 해결했던 다양한 문제를 넘파이의 벡터연산을 봉인하고 해결해보자.
# 예제1
– 아래를 리스트컴프리헨션을 이용하여 구현하라.
= np.array([1,2,3])
arr + 1 arr
array([2, 3, 4])
* 2 arr
array([2, 4, 6])
(풀이)
= [1,2,3] lst
+1 for l in lst] [l
[2, 3, 4]
*2 for l in lst] [l
[2, 4, 6]
#
# 예제2
– 아래를 리스트 컴프리헨션을 이용하여 구현하자.
= np.arange(1,11)
n = 3*n - 2
an an
array([ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28])
(풀이)
3*n-2 for n in range(1,11)] [
[1, 4, 7, 10, 13, 16, 19, 22, 25, 28]
#
# 예제3
– 아래의 코드에서 list(map(f,x))
대신에 리스트 컴프리헨션을 이용하라.
= np.arange(1,11)
x = lambda x: x+2
f list(map(f,x))
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
(풀이)
= lambda x: x+2
f for x in range(1,11)] [f(x)
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
#
팁: 반복계산을 해야할 경우
- 벡터화연산이 지원된다면 그것을 사용한다. (numpy, pandas)
- 불가능할 경우
map(f,x)
를 쓰거나 리스트컴프리헨션을 사용한다. - 그래도 안되는 경우
for
를 사용한다.