
키워드 인자 (Keyword-only Argument)
: 함수를 호출할 때 변수명=값 형태로 사용해야 하는 인자
: * 는 키워드 인자를 강제하기 위해 사용된다.
뒤쪽에 나오는 인자를 모두 키워드 인자로 받도록 강제한다.
( ' *, ' << 이렇게 사용 / 변수 앞에 바로 붙이지 않는다.)
포지셔널 인자 (Positional-only Argument)
: 함수를 호출할 때 값을 순서대로 전달해야 하는 인자
: /는 포지션 인자를 강제하기 위해 사용된다.
: / 앞에 있는 인자는 순서대로 전달해야 한다.
(포지셔널 인자로 받고 싶은 변수 뒤에 /를 단독으로 붙인다.)
def mix_func(a, b, /, h, i, *, x, y) :
print(a - b, h - i, x * y)
mix_func(15, 6, 6, h = 9, x = 3, y = 2) # 에러
mix_func(15, 6, i = 6, h = 9, x = 3, y = 2)
a, b는 포지셔널 인자 / x, y는 키워드 인자 / 나머지 h, i는 둘 다 가능하다.
이때 h도 키워드로 넘겨줬을 때 나머지만 순서대로 전달하면 될 거라고 생각했다.
하지만... 포지션 인자는 순서대로 채워지기 때문에 h를 중복으로 전달받았다고 생각해서 TypeError가 발생한다.
그래서 h를 키워드로 전달하고 싶을 경우엔 i도 키워드로 전달해야 한다.
def mul(x,y,/): #포지션 인자만 받겠다.
return x * y
mul(x=4,y=5)
포지션 인자만 받겠다고 맨 뒤에 /를 붙여놓고 값은 키워드로 전달했기 때문이다.
함수 정의할 때 파라미터 자리에서 /를 빼던지 값을 전달할 때 포지션 인자로 전달해야 한다.
def only_keyword(*,x,y): # 키워드 인자만 받겠다
return x + y
only_keyword(x=1,y=2)
only_keyword(1,2)
에러는 마지막 줄에서 난다.
함수를 정의할 때 * 를 사용해 키워드 인자만 받도록 정했기 때문에 포지션 인자로 값을 전ㄴ달하면 에러가 난다.
바로 윗 줄에서 한 것처럼 only_keyword(x = 1, y = 2) 이런 형태로 전달해야 한다.
def mix_fun(a,b,/,h,i,*,x,y):
print(a-b)
print(h-i)
print(x*y)
mix_fun( 파라미터 )
mix_fun(1, 2, 3, i = 4, x = 5, y = 6) # 출력 : -1, -1, 30
d = dict(a=1,b=2,c=3)
vo = d.items() # view 객체 생성
for kv in vo:
print(kv)
d['a'] = d['a'] + 3 # 값 수정
d['c'] += 2 # 값 수정
for kv in vo:
print(kv)
('a', 1)
('b', 2)
('c', 3)
('a', 4)
('b', 2)
('c', 5)
d.items()는 dict_items 객체 (뷰 객체)를 반환한다.
(튜플 형태로 반복 가능한 객체를 반환한다.)
뷰 객체는 복사본이 아닌 참조 객체이기 때문에 d의 현재 상태를 실시간으로 보여준다.
따라서 d의 값이 바뀌면 vo도 변경된 값을 반영한다.
d1 = dict(a=1,b=2,c=3)
d2 ={}
for k,v in d1.items():
d2[k] = v*2
print(d2)
===========================
#컴프리 헨션으로 채우시오.
d2 = { } ## d1의 값을 두 배 늘린 딕셔너리 생성
print(d2)
d1 = dict(a=1,b=2,c=3)
d2 = {k : v * 2 for k, v in d1.items()}
print(d2) # 출력 : {'a': 2, 'b': 4, 'c': 6}
map 함수는 반복 가능한 객체(리스트, 튜플 등)의 각 요소에 대해 주어진 함수를 적용하여 새로운 값을 반환하는 함수다.
-> map(함수, iterable)
iterable의 각 요소에 함수를 적용해 변환된 값을 가진 map 객체를 반환한다.
반환값은 map 객체이므로 list()나 tuple()로 변환해 사용해야 실제 값을 볼 수 있다.
반복 가능한 여러 iterable을 동시에 다룰 수도 있다.
# 리스트의 요소를 제곱으로 변환
nums = [range(1, 6)]
squared_nums = list(map(lambda x: x ** 2, nums))
print(squared_nums) # 출력: [1, 4, 9, 16, 25]
a, b = map(int, input().split())
난 문제를 풀 때 이런식으로 많이 썼다.
입력받은 문자열을 공백을 기준으로 나누어 리스트로 반환하고
그 요소들을 int함수에 적용하여 정수형으로 변환하여 각각 a와 b에 할당하는 것이다.
반복 가능한 객체의 각 요소에 대해 조건 함수를 적용하여 True인 값만 필터링하는 함수다.
-> filter(함수, iterable)
함수의 결과가 True인 요소만 반환하며 filter 객체 형태로 반환된다.
map과 마찬가지로 반환값은 filter 객체이므로 list()나 tuple()로 변환해 사용해야 한다.
조건 함수 대신 lambda 함수를 사용해 간단하게 필터링할 수도 있다.
# 짝수만 필터링
nums = [1, 2, 3, 4, 5]
even_nums = list(filter(lambda x: x % 2 == 0, nums))
print(even_nums) # 출력: [2, 4]
st1 = [1,2,3]
st2 = [3,2,1]
st3 = list(map(sum,st1,st2)) # 함수에 파라미터가 두개 있을 경우
st3 # 출력[4, 4, 4]
st1 = [1,2,3]
st2 = [3,2,1]
def sum (s, t) :
return s + t
st3 = list(map(sum,st1,st2)) # 함수에 파라미터가 두개 있을 경우
st3 # 출력[4, 4, 4]
s1 = ['one', 'two','three']
ref = list(map(함수,s1))
print(ref)
#['eno', 'owt', 'eerht']
def rev (lst) :
return lst[::-1]
s1 = ['one', 'two','three']
ref = list(map(rev,s1))
print(ref)
#['eno', 'owt', 'eerht']
users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'gender': 'M'},
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'gender': 'F'}]
def is_male(user) :
return user['gender']=='M'
m_user = list(filter(is_male, users))
for user in m_user :
print(user['name'])
# 출력 : 'Brett Holland'
def is_female(user) :
return user['gender']=='F'
f_users = list(filter(is_female, users))
for user in f_users :
print(user) # 출력 : Madison Martinez
# 아래 결과를 예측하시오.
nums = (1,2,3,4,5)
first, *others, last = nums
print(first, others, last) # 출력 : 1 [2, 3, 4] 5
nums의 첫 번째 요소는 first, 마지막 요소는 last에 할당된다.
나머지 요소는 리스트 형태로 others에 패킹된다.
* 사용 시의 차이함수에서 단독으로 쓰일때와 , 변수명 쓰일때의 차이는?
단독으로 쓰일 때
: 키워드 인자만 받을 것을 강제하기 위한 표시이다.
: 그 이후 인자들은 모두 키워드 인자로만 전달해야 한다.
함수 선언에서 *변수명
: 패킹 연산자로 가변 인자를 받을 때 사용한다.
: 여러 개의 인자를 튜플로 묶어서 하나의 변수에 할당한다.
함수 호출에서 *변수명
: 언패킹을 위해 사용된다.
: 리스트나 튜플의 요소를 함수의 개별 인자로 풀어서 전달할 때 사용되나.
def show_man(name, age, height) :
print(name, age, height)
p = ('Yoon', 20, 180)
show_man('Yoon', 20, 180)
show_man(*p)
*는 함수 호출 시 언패킹 연산자로 사용되며 튜플이나 리스트의 요소를 개별 인자로 풀어서 전달해 준다.
show_man(*p)는 p의 각 요소가 name, age, height에 각각 할당되므로 문제없이 작동한다.
show_man(p)의 결과가 궁금했는데 name = p로 인식해서 age, height를 전달받지 못 했기 때문에 TypeError가 뜬다.
c = Circle(10)
c.get_area() # 314~~~~
rec = Rectangle(10)
rec.get_area() # 100
class Circle :
def __init__(self, r) :
self.r = r
def get_area(self) :
return 3.14 * self.r **2
class Rectangle :
def __init__(self, length) :
self.length = length
def get_area(self) :
return self.length ** 2
c = Circle(10)
print(c.get_area()) # 출력 : 314
rec = Rectangle(10)
print(rec.get_area()) # 출력 : 100
세줄요약:
1.결과 데이터 반환을 위해 filter 와 컴프리 헨션으로 효율적 코딩 가능하다.
2.언패킹 하는 케이스는 튜플로 함수 호출 할때 이다.
3.함수 파라미터에서 단독으로 쓰일때와 파라미터명 으로 쓰일때를 구분하자
(해결 완료)
d = dic(a = 1, b = 2, c = 3)
vo = d.items()
for kv in vo :
print(kv)
1) 여기서 vo와 kv의 데이터 타입이 궁금했다.
: type( ) 함수를 통해 알아보니 각각 class <'dict.items> / class <'tuple> 이었다.
2) d와 vo가 같은지 궁금했다.
: 아침엔 <'dict'>와 <'dict.items'>의 차이를 몰랐다.
자세하게 안 읽고 앞부분만 보다보니 데이터 타입도 같고 값도 같네..? 라는 생각이 들었다.
알고보니 같은 내용을 참조하기 때문에 값이 같은 거였다.
d는 딕셔너리 / vo는 딕셔너리의 현재값을 반영해서 보여주는 뷰 객체(dict_items 객체)로 튜플 상의 뷰라고 한다.
아침에는 이게 너무 궁금해서 챗 GPT한테 엄청 물어봤다.
단어를 어떻게 말해야 할 지 모르겠어서 이거가 저거야? 이렇게 물어봐도 챗 GPT는 화를 안 낸다.
고마워 챗 GPT야
오늘 배운 것들을 크게 정리해보면 키워드 인자, 포지셔널 인자 / 뷰 객체 / 딕셔너리 컴프리헨션 / map(), filter() / 패킹과 언패킹
딕셔너리 컴프리헨션은 리스트와 다르게 딕셔너리가 있어야만 쓸 수 있어보이길래 쓸모없어보였는데 강사님께서 자주 쓰지는 않는다고 하셨다.. 역시....
* << 이거 보고 앗 포인터...? 싶어서 챗 GPT한테 물어봤는데 답변 읽고 있는 도중에 강사님께서 그 얘기를 고대로 하셔서 신기했다.ㅋㅋㅋㅋㅋ
내 화면을 다 보고 계시는 느낌이었다.
1학년 때 파이썬 배우면서 컴공으로 많이 몰렸다가
전공 결정하기 전에 C언어 포인터 배우고 나서 컴공 친구들이 많이 사라졌던 기억이 난다....ㅎ
내가 1학년 때 사귄 친구들은 반수 아님 타과로 가버린 친구들이었다...
