최근 몇 년간 파이썬 코딩 기술의 수요가 꾸준히 증가하고 있습니다. 파이썬 프로그래밍 역량을 키우는 데 도움이 되도록, 코드를 개선하는 데 사용할 수 있는 파이썬 트릭 30가지를 엄선했습니다. 앞으로 30일 동안 하루에 하나씩 익혀 보세요. 또한 코드 품질을 최상으로 유지하려면 파이썬 모범 사례 글도 확인해 보세요.
슬라이싱은 인덱싱에 기반해 시퀀스의 부분집합에 접근하도록 해 주는 파이썬의 기능입니다. 인덱스는 시퀀스에서 요소의 위치를 의미합니다. 시퀀스 타입이 가변(mutable)이라면 슬라이싱으로 데이터를 추출하고 수정할 수 있습니다.
참고: 불변(immutable) 시퀀스에도 슬라이싱을 사용할 수 있지만, 슬라이스를 수정하려 하면 TypeError가 발생합니다.
슬라이스의 기본 형식은 다음과 같습니다: sequence[start:stop:step]. start, stop, step 매개변수에 값을 지정하지 않으면 기본값이 적용됩니다. 기본값은 다음과 같습니다.
"start"는 기본적으로 0
"stop"은 시퀀스의 길이
"step"은 지정하지 않으면 1입니다.
sequence[start:stop]을 제공하면 시작 인덱스부터 stop - 1까지의 요소가 반환됩니다(종료 인덱스는 포함되지 않음).
음수 인덱스를 전달해 시퀀스를 뒤집는 등 다양한 작업도 가능합니다. 예를 들어, 4개 요소를 가진 리스트에서 0번째 인덱스는 -4와 같고, 마지막 인덱스는 -1과 같습니다. 위 예제 코드에서는 이 점을 step 매개변수에 적용했습니다. 그 결과 문자열이 끝에서 시작해 0번 인덱스까지 역순으로 출력됩니다.
#2 제자리 교환 / 동시 할당
a =10
b =5print(f"First: {a, b}")"""
First: (10, 5)
"""
a, b = b, a +2print(f"Second: {a, b}")"""
Second: (5, 12)
"""제공
Learn-by-Example 에디터, Tab을 눌러 입력하세요. Escape를 누른 후 Tab 또는 Shift+Tab을 눌러 탐색하세요.
리스트 컴프리헨션은 다른 이터러블로부터 리스트를 만드는 파이썬다운 방식입니다. for 루프보다 훨씬 빠릅니다. 그런데 대괄호 []를 둥근괄호 ()로 바꿔 버리면 어떻게 될까요? 제너레이터 객체가 됩니다.
파이썬에서는 리스트 컴프리헨션 로직을 둥근괄호로 감싸면 제너레이터 객체가 만들어집니다. 제너레이터는 특별한 종류의 이터러블입니다. 리스트와 달리 항목을 저장하지 않고, 각 요소를 순서대로 생성하는 방법과 현재 반복 상태만 저장합니다.
각 요소는 지연 평가라는 기법으로 요청될 때만 생성됩니다. 제너레이터를 사용하면 전체 시퀀스를 한 번에 만들지 않으므로 메모리를 덜 사용하는 것이 큰 장점입니다.
#5 별칭(aliasing)
a =[1,2,3,4,5]
b = a
# Change the 4th index in b
b[4]=7print(id(a))print(id(b))print(a)# Remember we did not explicitly make changes to a."""
15136008
15136008
[1, 2, 3, 4, 7]
"""제공
Learn-by-Example 에디터, Tab을 눌러 입력하세요. Escape를 누른 후 Tab 또는 Shift+Tab을 눌러 탐색하세요.
파이썬 팁 #13에서 언더스코어(_)에 마지막 평가 결과가 저장된다는 것을 봤지만, 이것이 전부는 아닙니다.
언더스코어는 프로그램에서 중요하지 않거나 이후에 사용하지 않을 객체를 나타내는 데도 사용됩니다. 식별자 대신 언더스코어(_)를 사용해야 하는 이유는 린팅 시 F841 오류가 발생하는 것을 막기 위해서입니다. F841 오류는 로컬 변수 이름이 할당되었지만 사용되지 않았음을 의미하며, 이는 좋지 않은 관행입니다.
언더스코어는 또한 정수, 부동소수, 복소수 리터럴에서 자리수 구분을 위한 시각적 구분자로 사용할 수 있습니다. 이는 파이썬 3.6에서 도입되었습니다.
목적은 길거나 특정 부분으로 구분되어 보이는 리터럴의 가독성을 높이는 것이었으며, 자세한 내용은 PEP 515에서 확인할 수 있습니다.
코드 스타일 & 문법 트릭
#18 __name__ == “__main__”
if __name__ =="__main__":print("Read on to understand what is going on when you do this.")"""
print("Read on to understand what is going on when you do this.")
"""제공
Learn-by-Example 에디터, Tab을 눌러 입력하세요. Escape를 누른 후 Tab 또는 Shift+Tab을 눌러 탐색하세요.
이 문법을 파이썬 프로그램에서 자주 보셨을 겁니다. 파이썬은 "__main__"이라는 특별한 이름을 사용하며, 실행 중인 파이썬 파일이 메인 프로그램일 때 이를 __name__ 식별자에 설정합니다.
위 모듈(파이썬 파일)을 다른 모듈로 가져와서 실행하면, 코드의 표현식은 거짓이 됩니다. 다른 모듈에서 임포트할 때는 __name__ 식별자가 모듈(파일) 이름으로 설정되기 때문입니다.
#19 ‘setdefault’ 메서드
import pprint
text ="It's the first of April. It's still cold in the UK. But I'm going to the museum so it should be a wonderful day"
counts ={}for word in text.split():
counts.setdefault(word,0)
counts[word]+=1
pprint.pprint(counts)"""
{'April.': 1,
'But': 1,
"I'm": 1,
"It's": 2,
'UK.': 1,
'a': 1,
'be': 1,
'cold': 1,
'day': 1,
'first': 1,
'going': 1,
'in': 1,
'it': 1,
'museum': 1,
'of': 1,
'should': 1,
'so': 1,
'still': 1,
'the': 3,
'to': 1,
'wonderful': 1}
"""제공
Learn-by-Example 에디터, Tab을 눌러 입력하세요. Escape를 누른 후 Tab 또는 Shift+Tab을 눌러 탐색하세요.
메서드에 전달하는 첫 번째 인수는 확인할 키이고, 두 번째 인수는 키가 없을 경우 설정할 값입니다. 키가 이미 존재한다면 메서드는 해당 값을 반환하므로 변경되지 않습니다.
프로그램 구조 트릭
#20 정규식 매칭
import re
number = re.compile(r"(0)?(\+44)?\d{10}")
num_1 = number.search("My number is +447999999999")
num_2 = number.search("My number is 07999999999")print(num_1.group())print(num_2.group())"""
'+447999999999'
'07999999999'
"""제공
Learn-by-Example 에디터, Tab을 눌러 입력하세요. Escape를 누른 후 Tab 또는 Shift+Tab을 눌러 탐색하세요.
print() 함수의 전체 기능을 모르는 파이썬 프로그래머가 의외로 많습니다. “Hello World”가 첫 프로그램이었다면, print()는 파이썬 학습 초기에 접한 내장 함수일 겁니다. 우리는 print()로 서식을 갖춘 메시지를 화면에 표시하지만, print()에는 그 이상이 있습니다.
위 코드에서는 서로 다른 방식으로 서식을 지정해 출력했습니다. sep 매개변수는 여러 객체를 인자로 전달할 때, 이들을 어떻게 구분해 출력할지 지정하는 선택적 인자입니다.
기본값은 공백으로 구분하는 것이지만, 예시처럼 sep을 ""로 설정하거나 "."로 설정해 동작을 바꿀 수 있습니다.
#23 람다 함수
defsquare(num:int)->int:return num **2print(f"Function call: {square(4)}")"""
Function call: 16
"""
square_lambda =lambda x: x**2print(f"Lambda function: {square_lambda(4)}")"""
Lambda functional: 16
"""
람다 함수는 파이썬으로 할 수 있는 중급-고급 주제로 이어집니다. 이 코스로 Intermediate Python을 학습해 보세요. 처음 보면 복잡해 보이지만, 사실 꽤 단순합니다.
예제 코드에서는 인수를 하나만 사용했지만, 원한다면 여러 개도 사용할 수 있습니다:
square =lambda a, b: a ** b
print(f"Lambda function: {square(4,2)}")"""
16
"""
본질적으로 lambda 키워드는 한 줄로 작고 제한된 익명 함수를 만들 수 있게 합니다. def 키워드로 선언한 일반 함수처럼 동작하지만, 이름이 없습니다.
#24 ‘swapcase’ 메서드
string ="SoMe RaNDoM sTriNg"print(string.swapcase())"""
sOmE rAndOm StRInG
"""제공
Learn-by-Example 에디터, Tab을 눌러 입력하세요. Escape를 누른 후 Tab 또는 Shift+Tab을 눌러 탐색하세요.
사용자가 비밀번호를 입력해야 하는 프로그램을 만든다고 가정해 봅시다. 비밀번호에는 숫자와 문자가 조합되어야 한다고 할 때, 문자열 인스턴스에서 isalnum()을 호출하면 한 줄로 확인할 수 있습니다.
이 메서드는 모든 문자가 알파벳(A-Za-z)과 숫자(0-9)인지 확인합니다. 공백이나 기호(!#%$&? 등)가 포함되어 있으면 False를 반환합니다.
#26 예외 처리
defget_ration(x:int, y:int)->int:try:
ratio = x/y
except ZeroDivisionError:
y = y +1
ratio = x/y
return ratio
print(get_ration(x=400, y=0))"""
400.0
"""
파이썬 프로그램은 오류를 만나면 종료됩니다.
하지만 항상 이런 동작을 원하지는 않습니다. 예를 들어 최종 사용자가 코드와 상호작용하는 경우, 프로그램이 조기에 종료되면 곤란하겠죠?
예외적인 상황을 처리하는 방법에는 여러 관점이 있습니다. 대부분의 파이썬 프로그래머는 보통 허락을 구하기보다 용서를 구하는 편이 쉽다는 철학을 따릅니다. 즉, 모든 예외 상황을 미리 방지하려 애쓰기보다, 예외가 발생했을 때 이를 처리할 수 있는 문맥을 제공해 오류를 잡아내는 방식을 선호합니다.
최근 몇 년간 파이썬 코딩 기술의 수요가 꾸준히 증가하고 있습니다. 파이썬 프로그래밍 역량을 키우는 데 도움이 되도록, 코드를 개선하는 데 사용할 수 있는 파이썬 트릭 30가지를 엄선했습니다. 앞으로 30일 동안 하루에 하나씩 익혀 보세요. 또한 코드 품질을 최상으로 유지하려면 파이썬 모범 사례 글도 확인해 보세요.
파이썬 실력이 아직 부족하다면, Python Programming 스킬 트랙으로 다듬을 수 있습니다.
시퀀스 & 자료 구조 트릭
#1 슬라이싱
슬라이싱은 인덱싱에 기반해 시퀀스의 부분집합에 접근하도록 해 주는 파이썬의 기능입니다. 인덱스는 시퀀스에서 요소의 위치를 의미합니다. 시퀀스 타입이 가변(mutable)이라면 슬라이싱으로 데이터를 추출하고 수정할 수 있습니다.
참고: 불변(immutable) 시퀀스에도 슬라이싱을 사용할 수 있지만, 슬라이스를 수정하려 하면 TypeError가 발생합니다.
슬라이스의 기본 형식은 다음과 같습니다: sequence[start:stop:step]. start, stop, step 매개변수에 값을 지정하지 않으면 기본값이 적용됩니다. 기본값은 다음과 같습니다.
sequence[start:stop]을 제공하면 시작 인덱스부터 stop - 1까지의 요소가 반환됩니다(종료 인덱스는 포함되지 않음).
음수 인덱스를 전달해 시퀀스를 뒤집는 등 다양한 작업도 가능합니다. 예를 들어, 4개 요소를 가진 리스트에서 0번째 인덱스는 -4와 같고, 마지막 인덱스는 -1과 같습니다. 위 예제 코드에서는 이 점을 step 매개변수에 적용했습니다. 그 결과 문자열이 끝에서 시작해 0번 인덱스까지 역순으로 출력됩니다.
#2 제자리 교환 / 동시 할당
처음에 b의 값이 12가 아니라 7이라고 생각했다면, 제자리 교환의 함정에 빠진 것입니다.
파이썬에서는 자동 언패킹으로 단일 대입문에서 이터러블을 여러 변수로 풀어낼 수 있습니다. 예를 들어:
*를 사용해 여러 값을 하나의 변수로 모을 수도 있는데, 이를 패킹이라고 합니다. 예시는 다음과 같습니다.
자동 패킹과 언패킹을 결합하면 동시 할당이라는 기법이 생깁니다. 동시 할당을 사용하면 일련의 값을 일련의 변수에 한 번에 할당할 수 있습니다.
#3 리스트 vs. 튜플
대부분의 파이썬 프로그래머는 리스트 자료 구조에 익숙합니다. 하지만 튜플은 상대적으로 덜 알려져 있습니다. 둘 다 이터러블이며 인덱싱이 가능하고 서로 다른 데이터 타입을 저장할 수 있습니다. 하지만 튜플을 리스트보다 선호해야 하는 상황이 있습니다.
무엇보다 리스트는 가변이므로 마음대로 수정할 수 있습니다:
반면 튜플은 불변이므로, 수정하려 하면 TypeError가 발생합니다.
이 때문에 튜플은 메모리를 더 효율적으로 사용합니다. 파이썬이 데이터에 필요한 정확한 메모리 블록을 할당할 수 있기 때문입니다. 반면 리스트는 확장될 가능성에 대비해 여유 메모리를 할당해야 하는데, 이를 동적 메모리 할당이라고 합니다.
요약: 데이터가 변경되지 않기를 원한다면, 메모리 관점에서 리스트보다 튜플을 사용하는 것이 좋습니다. 튜플은 리스트보다 더 빠르기도 합니다.
이 튜토리얼에서 파이썬 자료 구조에 대해 더 알아보세요.
#4 제너레이터
리스트 컴프리헨션은 다른 이터러블로부터 리스트를 만드는 파이썬다운 방식입니다. for 루프보다 훨씬 빠릅니다. 그런데 대괄호 []를 둥근괄호 ()로 바꿔 버리면 어떻게 될까요? 제너레이터 객체가 됩니다.
파이썬에서는 리스트 컴프리헨션 로직을 둥근괄호로 감싸면 제너레이터 객체가 만들어집니다. 제너레이터는 특별한 종류의 이터러블입니다. 리스트와 달리 항목을 저장하지 않고, 각 요소를 순서대로 생성하는 방법과 현재 반복 상태만 저장합니다.
각 요소는 지연 평가라는 기법으로 요청될 때만 생성됩니다. 제너레이터를 사용하면 전체 시퀀스를 한 번에 만들지 않으므로 메모리를 덜 사용하는 것이 큰 장점입니다.
#5 별칭(aliasing)
파이썬은 객체 지향 프로그래밍 언어로, 모든 것이 객체입니다. 따라서 객체를 식별자에 할당하는 것은 그 객체에 대한 참조를 만드는 것입니다.
한 식별자를 다른 식별자에 할당하면 두 식별자가 같은 객체를 참조하게 됩니다. 이를 별칭(aliasing)이라고 하며, 한쪽에서의 변경이 다른 쪽에도 영향을 미칩니다. 때로는 의도한 동작이지만, 종종 예기치 않게 발생합니다.
가변 객체를 사용할 때는 별칭을 피하는 것이 한 가지 방법입니다. 또 다른 해결책은 참조 대신 원본 객체의 복제본을 만드는 것입니다.
가장 간단한 복제 방법은 슬라이싱을 활용하는 것입니다:
이렇게 하면 b 식별자에 새로운 리스트 객체 참조가 생성됩니다.
그 외에도 데이터를 다른 식별자에 할당할 때 list(a)를 호출하거나 copy() 메서드를 사용하는 등 다양한 방법이 있습니다.
#6 ‘not’ 연산자
다음 파이썬 팁은 not 연산자를 사용해 자료 구조가 비어 있는지 확인하는 가장 쉬운 방법입니다. 파이썬의 내장 논리 연산자 not은 표현식이 참이 아니면 True를, 그렇지 않으면 False를 반환합니다. 즉, 불리언 표현식과 객체의 진릿값을 반전시킵니다.
if 문에서 다음과 같이 사용하는 것도 자주 볼 수 있습니다:
a가 True이면 not 연산자는 False를 반환하고, 그 반대도 마찬가지입니다.
처음엔 헷갈릴 수 있으니 직접 시도해 보세요.
문자열 & 출력 트릭
#7 F-문자열
가끔 문자열 객체를 포맷팅해야 할 때가 있습니다. 파이썬 3.6에서는 이 과정을 단순화하는 멋진 기능인 f-문자열이 도입되었습니다. 새 방식을 더 잘 이해하려면 도입 이전의 문자열 포맷팅 방식도 알아두면 좋습니다.
이전에는 다음과 같이 포맷팅했습니다:
새 포맷팅 방식은 더 빠르고, 가독성이 높고, 간결하며, 실수할 여지가 적습니다.
f-문자열의 또 다른 용도는 식별자 이름과 값을 함께 출력하는 것입니다. 이는 파이썬 3.8에서 도입되었습니다.
파이썬의 F-string Formatting 튜토리얼에서 더 알아보세요.
#8 print()의 ‘end’ 매개변수
print 문을 사용할 때 선택적 매개변수를 지정하지 않는 경우가 흔합니다. 이 때문에 출력 동작을 어느 정도 제어할 수 있다는 사실을 모르는 파이썬 사용자도 많습니다.
변경 가능한 선택적 매개변수 중 하나는 end입니다. end는 print 호출이 끝날 때 무엇을 표시할지 지정합니다.
end의 기본값은 "\n"으로, 새로운 줄을 시작하라는 의미입니다. 위 코드에서는 공백으로 바꿨습니다. 따라서 리스트의 모든 요소가 같은 줄에 출력됩니다.
#9 튜플에 추가하기
튜플은 불변입니다(파이썬 트릭 #3 리스트 vs. 튜플 참고). 튜플의 상태를 변경하려 하면 TypeError가 발생합니다. 하지만 튜플 객체를 변경 불가능한 바인딩으로 연결된 객체들의 이름 시퀀스로 생각하면 관점이 달라집니다.
튜플의 처음 두 요소는 정수로, 불변입니다. 마지막 요소는 리스트로, 파이썬에서 가변 객체입니다.
리스트를 변경 불가능한 바인딩을 가진 또 다른 이름으로 본다면, 튜플 내부에서 리스트 자체는 여전히 수정할 수 있음을 알 수 있습니다.
실무에서 이렇게 하길 권장하느냐고요? 아마도 아닙니다. 하지만 알아두면 유용한 지식입니다!
#10 딕셔너리 병합