변수의 범위(variable scope) - 전역 변수(global variable)
우리가 함수를 배우기 전까진 제일 바깥 영역인 전역 범위(global scope)에서 변수를 선언하고 활용했었습니다.
전역 범위에서 선언했기 때문에 그 변수를 스크립트 전체에서 접근 할 수 있었는데, 그 변수를 전역 변수(global variable)이라고
부릅니다.
global_variable = "this is global world"
print(f"global_variable in global_scope=> {global_variable}")
print(hex(id(global_variable)))
def local_world()
print(f"global_variable in local_world=> {global_variable}")
print(hex(id(global_variable)))
local_world()
# 결과값
# ID가 똑같이 나온다.
변수의 범위(variable scope) - 지역 변수(local variable)
그렇다면 함수 바디(local scope)에서 선언된 변수는 바깥에서 접근이 가능할까요?
NameError가 발생합니다. 즉 지역 변수는 변수를 만든 함수 안에서만 접근이 가능한 것을 확인 할 수 있습니다.
def my_little_world():
my_varialbe = "This is my little world."
print(my_variable)
# 에러발생
# Name Error : name 'my_variable' is not defined
변수의 범위(variable scope) - 지역 범위에서 전역 볌수 할당하기
지역 범위에서 전역 변수에 대한 접근이 가능하다고 했습니다. 그렇다면 지역 범위에서 전역 변수의 값을 변경하는 건 어떨까요?
아래의 예제에서 그 시도를 했을 때 결론은 변경이 안됐습니다. 지역 범위에서 할당하고 있는 'important_~' 변수는
사실 전역 변수가 아닌 지역 변수 였기 때문입니다.
- 전역변수와 지역변수는 변수명이 같더라도 서로 독립적으로 존재한다.
important_is_an_unbroekn_heart = '중요한 건 꺾이지 않는 마음'
def trials_and_tribulations():
important_is_an_unbroekn_heart = "흔들흔들"
trials_and_tribulations()
print(important_is_an_unbroekn_heart)
# 결과값
# 중요한 건 꺾이지 않는 마음
변수의 범위(variable scope) - 지역범위에서 전역 변수 할당하기
지역 범위에서 전역 변수의 값을 조회는 가능하나 변경에는 실패했습니다. 방법이 없을까요?
지역 범위에서 전역 변수를 변경하려면 global 키워드를 사용해야합니다.
global_variable = "변경이 됩니까?"
def heartbreaker():
global global_variable
global_variable = "global 키워드 활용해서 변경완료"
heartbreaker()
print(global_variable)
# 결과값
# global 키워드 활용해서 변경완료
함수 하나에 함수를 중첩해서 만들기
함수 바디 안에 def를 써서 다시 함수를 만들 수 있습니다.
level2 함수에서 바깥쪽 level1 함수의 지역 변수 message를 출력하고 있습니다.
level1에 선언된 지역변수는 level1 함수 바디 범위 내에서 접근 가능함을 알 수 있습니다.
def level1():
message = "This is Level 1."
def level2()
print(message)
level1()
# 결과값
# This is level 1.
안쪽 함수에서 바깥쪽 함수의 변수 변경해보기
안쪽 함수에서 바깥쪽 함수에 선언된 변수에 대한 출력이 가능한 것을 확인해봤습니다.
변경도 가능할까요?
def level1():
message = "This is level 1."
def level2():
message = "Level2 is better than level1."
level2()
print(message)
# 결과값
# This is level1
# -> 바깥쪽 함수 영역의 변수 값 변경에 실패했다.
nonlocal 키워드를 통해 바깥 영역의 변수를 사용하겠다고 설정하면 됩니다.
def level1():
message = "This is level 1."
def level2():
nonlocal message
message = "Level2 is better than level1."
level2()
print(message)
# 결과값
# Level2 is better than level1.
# 변경 성공
global, nonlocal 특징과 권고사항
- global 키워드는 함수의 중첩된 정도와 상관없이 전역 범위의 변수를 매칭합니다.
- 중첩된 함수마다 같은 이름이 있다면 nonlocal 키워드는 제일 가까운 바깥 변수를 매칭합니다.
- 가급적이면 함수마다 이름이 같은 변수를 사용하기보단 다른 변수명을 사용하는게 좋습니다.
변수 범위 정리
- 함수 안에서 선언한 변수는 함수를 호출해 실행되는 동안만 사용할 수 있습니다.
- 범위마다 같은 이름의 변수를 사용해도 각각 독립적으로 동작합니다.
- 지역변수(local variable)를 저장하는 이름 공간을 지역영역(local scope)라고 합니다.
- 전역 변수(global variable)를 저장하는 이름 공간을 전역 영역(global scope)라고 합니다.
- 파이썬 자체에서 정의한 이름 공간을 내장 영역(bulit-in scope)라고 합니다.
- 함수에서 변수를 호출하면 지역 영역 -> 전역 영역 -> 내장 영역 순으로 해당하는 변수를 확인합니다.
람다(lambda)
호출 될 때 값이 구해지는 하나의 표현식입니다. 또 이름이 없는 인라인 함수입니다.
# 람다, 매개변수 지정, 반환값으로 사용할 식
lambda parameters : expression
lambda x : x ** 2
람다 표현식을 바로 호출하는 방법입니다. 아래 예제와 같이 람다 표현식 전체를 소괄호(())로 감싸고 뒤에
함수 호출하듯이 소괄호를 붙입니다. 그리고 뒷쪽에 작성한 소괄호 안에 인수를 넣으면 람다 표현식이
바로 호출됩니다.
(lambda x : x + 10)(10)
# (lambda [parameters] : expression)(arguments)
람다는 기본적으로 이름 없는 함수(anonymous function)입니다.
람다로 만든 익명 함수를 호출하려면 변수에 할당해서 사용할 수 있습니다
(파이썬에서는 함수는 일급 객체(first_class_object)입니다.
twice = lambda x : x * 2
print(twice(10))
람다의 expression 부분은 변수 없이 식 한줄로 표현 가능(인라인) 해야합니다.
따라서 람다식 안에 새 변수를 만들 수 없습니다. 변수가 필요한 경우는
def를 써서 함수를 정의해서 사용하는 것이 좋습니다.
(lambda x : y = 10; x + y)(1)
# invalid syntax error
조건 표현식(Conditional Expression), inline if else
if else를 한줄로 작성할 수 있는 방법입니다.
lambda에 사용하면 활용도가 아주 좋습니다. if만 사용할 수는 없습니다.
반드시 else와 같이 써야합니다. 중첩해서 사용 가능합니다.
다만 중첩이 너무 많아지면 파악이 어려우니 가독성 좋게 쓰는게 더 좋겠습니다.
elif는 없습니다.
True일 때 값 if 조건식 else False일 때 값
score = 90
'A' if 90 < score < 100 else 'B' if 80 < score else 'c'
람다(lambda) feat. map()
람다와 map() 함수를 같이 쓸 때 다음과 같이 사용합니다. 이 때 필요에 따라
parameter와 iterable의 개수를 맞춰서 사용하면 됩니다. 어느 한쪽 iterable의 길이가 짧아도
상관없이 동작하며, 길이가 작은 쪽에 맞춰 값을 반환합니다.
map(lambda parameter1, parameter2, ...: expression, iterable1, iterable2,...)
a = [_ for _ in range(1,6)]
b = [_ for _ in range(2,11,2)]
print(list(map(lambda x, y : x * y, a , b)))
# 한 줄로 표현하기
print((lambda x : x ** 2)(10))
람다(lambda) feat.filter()
람다와 filter() 함수를 같이 쓸 때 다음과 같이 사용합니다. filter의 첫 인수로 들어가는 함수의
반환값이 True 일 때만 해당 요소를 가져옵니다. 리스트 컴프리헨션으로도 표현 가능한 부분입니다.
(속도와 가독성 모두 리스트 컴프리헨션이 더 낫습니다.)
a = [3,2,8,22,10,7,0,11,9,9]
list(filter(lambda x : x % 3 == 0 and 0 < x < 10, a))
# 리스트컴프리헨션으로 작성했을 때
[x for x in a if x % 3 == 0 and 0 < x < 10]
'데이터 분석 및 시각화 > 파이썬' 카테고리의 다른 글
[Python] 기초 정리(Numpy) (0) | 2023.01.16 |
---|---|
[Python] 기초 정리(Class) (1) | 2023.01.13 |
[Python] 기초 정리(함수, 문자열 메서드 join) (0) | 2023.01.12 |
[Python] 기초 정리(tuple, random, set) (0) | 2023.01.11 |
[Python] 메모리에 객체를 저장하는 구조 (0) | 2023.01.11 |