본문으로 바로가기

예제로 알아보는 더 나은 코드를 위한 파이썬 트릭 30선

코드를 개선하고 파이썬 실력을 키우는 데 활용할 수 있는 파이썬 트릭 30가지를 엄선했습니다.
업데이트됨 2026년 5월 29일  · 15분 읽다

최근 몇 년 사이 파이썬 코딩 역량에 대한 수요가 크게 늘었습니다. 파이썬 프로그래밍 실력을 키우는 데 도움이 되도록, 코드를 개선하는 데 쓸 수 있는 파이썬 트릭 30가지를 모았습니다. 앞으로 30일 동안 하루에 하나씩 익혀 보세요. 또 코드가 최고 수준을 유지하도록 파이썬 베스트 프랙티스 글도 확인해 보세요. 

파이썬 실력이 아직 부족하다고 느낀다면 Python Skill Track으로 탄탄하게 다질 수 있습니다.

시퀀스 & 자료구조 트릭

#1 슬라이싱

a = "Hello World!"
print(a[::-1])

"""
!dlroW olleH
"""

슬라이싱은 인덱싱을 기반으로 시퀀스의 부분집합에 접근하게 해 주는 파이썬의 기능입니다. 인덱스는 시퀀스에서 요소의 위치를 의미합니다. 시퀀스 타입이 가변(mutable)이라면 슬라이싱으로 데이터를 추출하고 수정할 수 있습니다. 

참고: 불변(immutable) 시퀀스에도 슬라이싱은 사용할 수 있지만, 슬라이스를 수정하려 하면 TypeError가 발생합니다. 

슬라이스의 형식은 다음과 같습니다: sequence[start:stop:step]. start, stop, step 값을 지정하지 않으면 기본값이 적용됩니다. 기본값은 다음과 같습니다: 

  • "start"는 기본적으로 0 
  • "stop"은 기본적으로 시퀀스의 길이
  • "step"은 지정하지 않으면 기본적으로 1입니다. 

sequence[start:stop]을 사용하면 시작 인덱스부터 stop - 1까지의 요소가 반환됩니다(Stop 인덱스는 포함되지 않음). 

음수 인덱스를 전달해 시퀀스를 뒤집는 것도 가능합니다. 예를 들어, 4개 요소의 리스트에서 0번째 인덱스는 -4이기도 하며, 마지막 인덱스는 -1이기도 합니다. 위 예제 코드에서는 이 점을 시퀀스의 step 매개변수에 적용했습니다. 그 결과, 문자열이 끝에서 시작해 인덱스 0까지 역순으로 출력되었습니다.   

#2 제자리 교환 / 동시 할당

a = 10
b = 5
print(f"First: {a, b}")

"""
First: (10, 5)
"""

a, b = b, a + 2
print(f"Second: {a, b}")

"""
Second: (5, 12)
"""

처음에 b의 값이 12가 아니라 7일 거라고 생각했다면, 제자리(swapping) 교환의 함정에 빠진 것입니다. 

파이썬에서는 자동 언패킹으로 단 한 줄의 할당문에서 이터러블을 여러 변수로 풀어낼 수 있습니다. 예를 들어: 

a, b, c = [1, 2, 3]
print(a)
print(b)
print(c)

"""
1
2
3
"""

*를 사용해 여러 값을 하나의 변수로 모을 수도 있습니다. 이 파이썬 트릭을 패킹이라 부릅니다. 아래는 패킹의 예시입니다.  

a, *b = 1, 2, 3
print(a, b)
"""
1 [2, 3]
"""

자동 패킹과 언패킹을 결합하면 동시 할당이라 불리는 기법이 생깁니다. 동시 할당을 사용하면 일련의 값을 일련의 변수에 한 번에 할당할 수 있습니다.

#3 리스트 vs. 튜플 

import sys

a = [1, 2, 3, 4, 5]
b = (1, 2, 3, 4, 5)

print(f"List size: {sys.getsizeof(a)} bytes")
print(f"Tuple size: {sys.getsizeof(b)} bytes")

"""
List size: 52 bytes
Tuple size: 40 bytes
"""

대부분의 파이썬 프로그래머는 리스트 자료구조에 익숙하지만, 튜플은 그렇지 않을 수 있습니다. 둘 다 이터러블이며, 인덱싱이 가능하고, 서로 다른 자료형을 함께 저장할 수 있습니다. 하지만 리스트보다 튜플이 유리한 상황이 있습니다. 

우선 리스트는 가변형이어서 마음대로 수정할 수 있습니다: 

a = [1,2,3,4,5]
a[2] = 8
print(a)

"""
[1,2,8,4,5]
"""

반면 튜플은 불변형이어서 수정하려 하면 TypeError가 발생합니다. 

이 때문에 튜플은 메모리를 더 효율적으로 사용합니다. 파이썬이 데이터에 필요한 정확한 메모리 블록만 할당할 수 있기 때문입니다. 반면 리스트는 확장 가능성에 대비해 여분의 메모리를 잡아두어야 합니다. 이를 동적 메모리 할당이라 합니다. 

요약: 데이터가 변경되지 않아야 하는 상황에서는 메모리 측면에서 리스트보다 튜플을 선호하는 것이 좋습니다. 튜플은 리스트보다 더 빠르기도 합니다. 

이 튜토리얼에서 파이썬 자료구조를 더 알아보세요. 

#4 제너레이터

a = [x * 2 for x in range(10)]
b = (x * 2 for x in range(10))

print(a)
print(b)

"""
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
<generator object <genexpr> at 0x7f61f8808b50>
"""

리스트 컴프리헨션은 다른 이터러블에서 리스트를 만드는 파이써닉한 방법으로, for 루프보다 훨씬 빠릅니다. 그런데 대괄호 []를 실수로 소괄호 ()로 바꾸면 어떻게 될까요? 제너레이터 객체가 만들어집니다.

파이썬에서 리스트 컴프리헨션 로직에 소괄호를 쓰면 제너레이터 객체가 생성됩니다. 제너레이터는 특별한 종류의 이터러블입니다. 리스트와 달리 항목을 저장하지 않고, 각 요소를 순서대로 생성하는 지시와 현재 반복 상태만 저장합니다.

각 요소는 지연 평가라는 기법으로 요청될 때만 생성됩니다. 제너레이터를 쓰는 이 파이썬 팁의 핵심 장점은 전체 시퀀스를 한 번에 만들지 않기 때문에 메모리를 덜 사용한다는 점입니다. 

#5 별칭(aliasing) 

a = [1, 2, 3, 4 ,5]
b = a

# Change the 4th index in b
b[4] = 7

print(id(a))
print(id(b))
print(a) # Remember we did not explicitly make changes to a.

"""
15136008
15136008
[1, 2, 3, 4, 7]
"""

파이썬은 객체 지향 언어로, 모든 것이 객체입니다. 따라서 객체를 식별자에 할당하는 행위는 그 객체에 대한 참조를 만드는 것입니다. 

한 식별자를 다른 식별자에 할당하면, 같은 객체를 참조하는 두 식별자가 생깁니다. 이를 별칭(aliasing)이라 하며, 한쪽에서의 변경이 다른 쪽에도 영향을 미칩니다. 때로는 이런 동작이 유용하지만, 종종 예상치 못하게 우리를 곤란하게 만들기도 합니다. 

이를 피하는 한 가지 방법은 가변 객체를 사용할 때 별칭을 만들지 않는 것입니다. 또 다른 방법은 참조 대신 원본 객체의 복제본을 만드는 것입니다. 

가장 간단한 복제 방법은 슬라이싱을 활용하는 것입니다: 

b = a[:] 

이렇게 하면 b 식별자에 새로운 리스트 객체 참조가 생성됩니다. 

그 밖에도 데이터를 다른 식별자에 할당할 때 list(a)를 호출하거나 copy() 메서드를 쓰는 등 다양한 방법이 있습니다. 

#6 ‘not’ 연산자

a = []
print(not a)

"""
True
"""

다음 파이썬 팁은 not 연산자를 사용해 자료구조가 비어 있는지 확인하는 가장 쉬운 방법입니다. 파이썬의 내장 not은 논리 연산자로, 표현식이 참이 아니면 True를, 그렇지 않으면 False를 반환합니다. 즉, 불리언 표현식과 객체의 진릿값을 반전시킵니다.  

if 문에서 다음과 같이 사용하는 경우도 많이 볼 수 있습니다: 

if not a:
    # do something... 

aTrue이면 not 연산자는 False를 반환하고, 그 반대도 마찬가지입니다. 

처음엔 헷갈릴 수 있으니 직접 시도해 보세요.

문자열 & 출력 트릭

#7 F-문자열

first_name = "John"
age = 19

print(f"Hi, I'm {first_name} and I'm {age} years old!")

"""
Hi, I'm John and I'm 19 years old!
"""

가끔 문자열 객체를 서식화해야 할 때가 있는데, 파이썬 3.6에서 이를 단순화하는 멋진 기능인 f-문자열이 도입되었습니다. 새 방식을 제대로 이해하려면 이전에 문자열을 어떻게 포매팅했는지 알아두면 도움이 됩니다. 

이전 문자열 포매팅 방식은 다음과 같습니다: 

first_name = "John"
age  = 19

print("Hi, I'm {} and I'm {} years old!".format(first_name, age))

"""
Hi, I'm John and I'm 19 years old!
"""

본질적으로 새로운 포매팅 방식은 더 빠르고, 더 읽기 쉽고, 더 간결하며, 실수하기도 더 어렵습니다.

f-문자열의 또 다른 용도는 식별자 이름과 그 값을 함께 출력하는 것입니다. 이는 파이썬 3.8에서 도입되었습니다.

x = 10
y = 20
print(f"{x = }, {y = }")

"""
x = 10, y = 20
"""

파이썬의 F-string 포매팅 튜토리얼에서 더 알아보세요. 

#8 print() 함수의 ‘end’ 매개변수

languages = ["english", "french", "spanish", "german", "twi"]
print(' '.join(languages))

"""
english french spanish german twi
"""

옵션 매개변수를 지정하지 않고 print 문을 사용하는 경우가 매우 흔합니다. 그 결과, 출력 형식을 어느 정도 제어할 수 있다는 사실을 모르는 파이썬 사용자도 많습니다.

변경할 수 있는 선택적 매개변수 중 하나가 end입니다. end 매개변수는 print 호출의 끝에 무엇을 표시할지 지정합니다. 

end의 기본값은 "\n"으로, 파이썬에 새 줄을 시작하라고 지시합니다. 위 코드에서는 이를 공백으로 바꿨습니다. 따라서 리스트의 모든 요소가 한 줄에 출력됩니다.

#9 튜플에 요소 추가

a = (1, 2, [1, 2, 3])
a[2].append(4)
print(a)

"""
(1, 2, [1, 2, 3, 4])
"""

튜플은 불변이라는 사실은 이미 알고 있습니다(파이썬 트릭 #3 리스트 vs. 튜플 참조). 튜플의 상태를 바꾸려 하면 TypeError가 발생합니다. 하지만 튜플 객체를 변경할 수 없는 객체에 바인딩된 이름의 시퀀스로 생각하면 다른 관점이 보입니다.

우리 튜플의 처음 두 요소는 정수로, 불변입니다. 마지막 요소는 리스트로, 파이썬에서 가변 객체입니다.

리스트를 변경할 수 없는 객체에 바인딩된 또 하나의 이름으로 본다면, 튜플 내부에서도 그 리스트는 여전히 수정할 수 있다는 점을 깨닫게 됩니다.

실무에서 이렇게 하길 권하느냐고요? 아마 아닐 겁니다. 하지만 알아두면 유용한 상식입니다!

#10 딕셔너리 병합

a = {"a": 1, "b": 2}
b = {"c": 3, "d": 4}

a_and_b = a | b
print(a_and_b)

"""
{"a": 1, "b": 2, "c": 3, "d": 4}
"""

파이썬 3.9 이상에서는 | (비트 OR)로 딕셔너리를 병합할 수 있습니다. 이 파이썬 트릭에 대해 더 덧붙일 말은 많지 않습니다. 훨씬 더 읽기 쉬운 해법이라는 점만 기억하세요! 

코드 스타일 & 문법 트릭

#11 삼항 연산자 / 조건식 

condition = True
name = "John" if condition else "Doe"

print(name)

"""
John
"""

위 코드에는 이른바 삼항 연산자가 보입니다. 조건식이라고도 합니다. 삼항 연산자는 조건이 True인지 False인지에 따라 값을 평가하는 데 사용합니다.

같은 코드를 다음처럼 쓸 수도 있습니다:

condition = True
if condition:
    name = "John"
else:
    name = "Doe"

print(name)
"""
John
"""

두 코드 모두 결과는 같지만, 삼항 조건식을 쓰면 훨씬 짧고 명확하게 작성할 수 있습니다. 파이써닉한 방식이죠. 

#12 리스트에서 중복 제거

a = [1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 2, 2]
print(list(set(a)))

"""
[1, 2, 3, 4, 5, 6, 7]
"""

리스트에서 중복 요소를 제거하는 가장 간단한 방법은 리스트를 집합으로 변환했다가(필요하면) 다시 리스트로 바꾸는 것입니다.

가변성 관점에서 집합과 리스트는 꽤 비슷합니다. 두 자료구조 모두 요소를 자유롭게 추가/삭제할 수 있지만, 여전히 매우 다릅니다.

리스트는 순서가 있고 0부터 인덱싱되며 가변입니다. 집합은 순서가 없고 인덱싱되지 않습니다. 집합의 요소는 불변 타입이어야 하며(집합 자체는 가변), 인덱스로 요소를 가져오거나 요소 자체를 수정하려 하면 에러가 발생합니다.

집합과 리스트의 또 다른 핵심 차이는 집합에는 중복이 허용되지 않는다는 점입니다. 이 성질 덕분에 리스트의 중복 요소를 제거할 수 있었습니다.

#13 독립 언더스코어 

>>> print(_)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>

>>> 1 + 2
3

>>> print(_)
3

언더스코어(_)는 파이썬에서 합법적인 식별자이므로 객체를 참조하는 데 사용할 수 있습니다. 하지만 언더스코어에는 또 다른 역할이 있습니다. 마지막 평가 결과를 저장하는 것입니다.

문서에 따르면 “대화형 인터프리터는 마지막 평가 결과를 _ 변수에서 사용할 수 있게 합니다(내장 함수 print와 함께 builtins 모듈에 저장됨).”

첫 줄에서 언더스코어를 호출하기 전에 어떤 객체도 할당하지 않았으므로 에러가 발생했습니다. 하지만 1 + 2의 결과를 계산하자 대화형 인터프리터는 그 결과를 _ 식별자에 저장해 주었습니다. 

#14 값을 무시하기 위한 언더스코어

for _ in range(100):
    print("The index doesn't matter")

"""
The index doesn't matter
The index doesn't matter
...
"""

파이썬 팁 #13에서 언더스코어(_) 식별자에 마지막 평가 결과가 담긴다는 것을 보았습니다. 하지만 이것이 전부는 아닙니다.

프로그램에서 신경 쓰지 않거나 이후에 사용할 일이 없는 객체를 표현하는 데도 사용할 수 있습니다. 언더스코어(_) 대신 일반 식별자를 사용하면 린팅 시 F841 오류가 발생합니다. F841 오류는 지역 변수 이름이 할당되었지만 사용되지 않았음을 의미하며, 좋지 않은 관행입니다.

#15 후행 언더스코어

list_ = [0, 1, 2, 3, 4]
global_ = "Hi there" 

앞선 두 가지 트릭에 이어, 파이썬의 언더스코어(_) 사용법 중 또 하나는 파이썬 키워드와의 충돌을 피하는 것입니다. 

PEP 8은 후행 언더스코어(_)를 “파이썬 키워드와의 충돌을 피하기 위한 관례”로 사용할 것을 권합니다. 또한 “약어나 이상한 철자를 쓰기보다 단일 후행 언더스코어를 붙이는 것이 일반적으로 더 낫다. 따라서 list_lst보다 낫다.”고 명시합니다.

#16 선행 언더스코어

class Example:
    def __init__(self):
        self._internal = 2
        self.external = 20

숙련된 파이썬 프로그래머가 식별자나 메서드 이름 앞에 언더스코어를 붙이는 경우를 자주 보게 됩니다. 그럴만한 이유가 있습니다.

식별자나 메서드 앞의 언더스코어는 숨은 의미가 있습니다. 해당 변수나 메서드는 내부 용도로만 쓰인다는 의미의 선언(disclaimer)입니다. 본질적으로 PEP 8에서 정의한 관례이며, 파이썬이 강제하는 것은 아닙니다. 따라서 선행 언더스코어는 약한 신호에 불과합니다.

자바와 달리 파이썬에는 private/public 변수의 강한 구분이 없습니다. 즉, 커뮤니티가 의미를 부여했기에 의미가 있을 뿐이며, 이를 붙인다고 프로그램 동작이 달라지지는 않습니다.

#17 언더스코어 시각 구분

언더스코어에 관한 마지막 팁입니다. 지금까지 세 가지 용도를 살펴봤습니다. 더 알고 싶다면 파이썬에서 언더스코어(_)의 역할 튜토리얼을 참고하세요. 

number = 1_500_000
print(number)

"""
15000000
"""

언더스코어를 정수, 부동소수, 복소수 리터럴에서 자리 구분을 위한 시각적 구분자로 사용할 수도 있습니다. 이는 파이썬 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.")
"""

여러 파이썬 프로그램에서 이 구문을 보셨을 가능성이 큽니다. 파이썬은 "__main__"이라는 특별한 이름을 사용하며, 실행 중인 파이썬 파일이 메인 프로그램일 때 이를 __name__ 식별자에 설정합니다.

만약 스크린샷의 모듈(파이썬 파일)을 다른 모듈로 가져와(import) 그 파일을 실행하면, 코드의 표현식은 거짓이 됩니다. 다른 모듈에서 가져오면 __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}
"""

딕셔너리의 여러 키에 값을 세팅하고 싶을 때가 있습니다. 예를 들어 말뭉치에서 단어의 빈도를 집계할 때요. 일반적인 방법은 다음과 같습니다: 

  1. 키가 딕셔너리에 존재하는지 확인한다.
  2. 존재하면 값을 1 증가시킨다.
  3. 존재하지 않으면 추가하고 값을 1로 설정한다.

코드로 쓰면 다음과 같습니다:

counts = {}
for word in text.split():
    if word in counts:
        counts[word] += 1
    else:
      counts[word] = 1

이를 더 간결하게 하는 방법이 딕셔너리 객체의 setdefault() 메서드를 사용하는 것입니다.

첫 번째 인자는 확인하려는 키입니다. 두 번째 인자는 그 키가 딕셔너리에 없을 때 설정할 값입니다. 키가 이미 존재한다면 메서드는 해당 값을 반환하며, 변경하지 않습니다.

프로그램 구조 트릭

#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'
"""

정규식은 검색할 텍스트 패턴을 지정하게 해 줍니다. 대부분 CTRL + F(윈도우)로 검색할 수 있다는 것은 알지만, 정확히 무엇을 찾는지 모른다면 어떻게 찾아야 할까요? 답은 패턴을 검색하는 것입니다.  

예를 들어, 영국 전화번호는 비슷한 패턴을 따릅니다. 맨 앞이 0이고 그 뒤에 숫자 10개가 오거나, 국제 표기인 +44 뒤에 숫자 10개가 옵니다. 

정규식은 시간을 크게 절약해 줍니다. 위 예시를 정규식 대신 규칙으로 코딩하려 했다면 10줄 이상의 코드가 필요할 수 있습니다. 

정규식은 코드를 작성하지 않더라도 배워 둘 가치가 있습니다. 대부분의 최신 텍스트 에디터와 워드 프로세서는 정규식을 사용해 찾기/바꾸기를 지원합니다.

#21 정규식 파이프

import re

heros = re.compile(r"Super(man|woman|human)")

h1 = heros.search("This will find Superman")
h2 =  heros.search("This will find Superwoman")
h3 = heros.search("This will find Superhuman")

print(h1.group())
print(h2.group())
print(h3.group())

"""
Superman
Superwoman
Superhuman
"""

정규식에는 파이프(|)라는 특수 문자가 있어 여러 표현식 중 하나를 매칭할 수 있습니다. 어디서든 사용할 수 있어, 비슷한 패턴이 여럿 있을 때 아주 유용합니다.

예를 들어 'Superman', 'Superwoman', 'Superhuman'은 접두사가 같습니다. 반복되는 부분은 그대로 두고, 달라져야 하는 부분만 파이프로 표현할 수 있습니다. 다시 한 번, 소중한 시간을 절약할 수 있습니다.

주의할 점: 매칭하려는 표현식이 모두 같은 텍스트에 등장한다면, 처음 매칭되는 항목만 반환됩니다. 예: "An example text containing Superwoman, Superman, Superhuman"에서는 Superwoman이 반환됩니다.

#22 print() 함수의 ‘sep’ 매개변수

day = "04"
month = "10"
year = "2022"

print(day, month, year)
print(day, month, year, sep = "")
print(day, month, year, sep = ".")

"""
04 10 2022
04/10/2022
04.10.2022
"""

print() 함수의 전체 기능을 모르는 파이썬 프로그래머가 많습니다. “Hello World”가 첫 프로그램이었다면, print()는 아마 파이썬을 배우며 가장 먼저 접한 내장 함수일 것입니다. 화면에 서식화된 메시지를 표시하는 데 쓰지만, print()에는 그 이상이 있습니다. 

위 코드에서는 다양한 방식으로 서식화된 메시지를 표시했습니다. sep 매개변수는 print() 함수의 선택적 인자로, 여러 객체를 함께 출력할 때 무엇으로 구분할지 지정합니다. 

기본값은 공백이지만, 예시에서는 이를 바꿨습니다. 하나는 sep""로, 다른 하나는 "."로 설정했습니다.

#23 람다 함수 

def square(num:int) -> int:
    return num ** 2

print(f"Function call: {square(4)}")
"""
Function call: 16
"""

square_lambda = lambda x: x**2
print(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
"""

swapcase() 메서드는 문자열 객체에 적용해 대문자를 소문자로, 소문자를 대문자로 한 줄로 바꿔 줍니다. swapcase()의 활용 사례가 아주 많지는 않지만, 알아두면 좋습니다.

#25 ‘isalnum’ 메서드

password = "ABCabc123"
print(password.isalnum())

"""
True
"""

사용자에게 비밀번호 입력을 요구하는 프로그램을 만든다고 가정해 봅시다. 숫자와 문자의 조합을 포함해야 한다면, 문자열 인스턴스에서 isalnum()을 호출해 한 줄로 검사할 수 있습니다.

이 메서드는 모든 문자가 알파벳(A-Za-z) 또는 숫자(0-9)인지 확인합니다. 공백이나 기호(!#%$&? 등)가 포함되어 있으면 False를 반환합니다.

#26 예외 처리

def get_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
"""

파이썬 프로그램은 에러를 만나면 종료됩니다.

하지만 항상 이런 동작을 원하지는 않습니다. 예를 들어 최종 사용자가 코드와 상호작용하는 상황을 생각해 보세요. 그때 프로그램이 일찍 종료된다면 얼마나 곤란할까요?

예외적인 경우를 다루는 방법에는 여러 관점이 있습니다. 대부분의 파이썬 프로그래머는 대체로 “허락을 구하기보다 용서를 구하는 편이 쉽다”는 생각을 받아들입니다. 즉, 모든 예외 상황을 사전에 방지하려 애쓰기보다, 예외를 처리할 수 있는 주변 문맥을 제공해 발생한 에러를 잡아내는 방식을 선호합니다.

다만 이는 문제가 발생한 후에 대처할 메커니즘이 있을 때만 유효합니다.

#27 리스트 간 차이 식별

list_1 = [1, 3, 5, 7, 8]
list_2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

solution_1 = list(set(list_2) - set(list_1))
solution_2 = list(set(list_1) ^ set(list_2))
solution_3 = list(set(list_1).symmetric_difference(set(list_2)))

print(f"Solution 1: {solution_1}")
print(f"Solution 2: {solution_2}")
print(f"Solution 3: {solution_3}")

"""
Solution 1: [9, 2, 4, 6]
Solution 2: [2, 4, 6, 9]
Solution 3: [2, 4, 6, 9]
"""

파이썬에서 두 리스트의 차이를 비교하는 세 가지 방법입니다. 

참고: list_1list_2의 부분집합이라는 사실을 확실히 알지 못한다면, 솔루션 1은 나머지 두 솔루션과 동일하지 않습니다.

#28 Args & kwargs

def some_function(*args, **kwargs):
    print(f"Args: {args}")
    print(f"Kwargs: {kwargs}")

some_function(1, 2, 3,  a=4, b=5, c=6)

"""
Args: (1, 2, 3)
Kwargs: {'a': 4, 'b': 5, 'c': 6}
"""

함수가 몇 개의 변수를 받을지 알 수 없을 때 *args**kwargs를 매개변수로 사용합니다. 

*args는 키워드가 아닌 위치 인자를 가변 개수로 전달할 수 있게 해 줍니다(즉, 이름이 필요 없는 인자). 반면 **kwargs는 임의 개수의 키워드 인자를 전달할 수 있게 해 줍니다.

사실 *args와 **kwargs라는 단어 자체가 특별한 것은 아닙니다. 마법은 별표(*)에 있습니다. 별표 뒤의 단어는 무엇이든 될 수 있지만, argskwargs를 사용하는 것이 일반적이며 파이썬 개발자들 사이에서 관례로 굳어졌습니다. 

#29 Ellipsis(줄임표)

print(...)

"""
Ellipsis
"""

def some_function():
    ...

# Alternative solution
def another_function():
    pass

Ellipsis는 파이썬 객체로, 마침표 세 개(...)로 쓰거나 객체 자체(Ellipsis)를 호출해 사용할 수 있습니다.

가장 잘 알려진 용도는 NumPy에서 다차원 배열에 접근하거나 슬라이싱할 때입니다. 예를 들어:

import numpy as np

arr = np.array([[2,3], [1,2], [9,8]])

print(arr[...,0])
"""
[2 1 9]
"""
print(arr[...])

"""
[[2 3]
[1 2]
[9 8]]
"""

Ellipsis의 또 다른 용도는 구현되지 않은 함수의 플레이스홀더로 쓰는 것입니다. 

즉, Ellipsis, ..., 또는 pass를 넣어도 모두 유효합니다.

#30 리스트 컴프리헨션

even_numbers = [x for x in range(10) if x % 2 == 0 and x != 0]
print(even_numbers)

"""
[2, 4, 6, 8]
"""

마지막 파이썬 트릭은 리스트 컴프리헨션입니다. 다른 시퀀스에서 리스트를 우아하게 만드는 방법으로, 위 코드처럼 정교한 로직과 필터링을 수행할 수 있습니다.

같은 목적을 달성하는 다른 방법도 있습니다. 예를 들어 람다 함수를 다음과 같이 사용할 수 있습니다:

even_numbers = list(filter(lambda x: x % 2 ==0 and x != 0, range(10)))
print(even_numbers)
"""
[0, 2, 4, 6, 8]
"""

하지만 많은 파이썬 사용자들은 이 해법이 리스트 컴프리헨션보다 읽기 어렵다고 말할 것입니다.

FAQs

초보자에게 가장 유용한 파이썬 트릭은 무엇인가요?

초보자에게는 F-문자열이 아마 가장 즉시 유용합니다. .format() 같은 이전 방식보다 문자열 포매팅이 더 빠르고, 더 읽기 쉽고, 실수하기도 더 어렵습니다.

파이썬에서 두 변수를 가장 빠르게 바꾸는 방법은?

동시 할당을 사용하세요: a, b = b, a. 임시 변수가 필요 없습니다. 파이썬은 할당 전에 오른쪽을 완전히 평가합니다.

한 줄로 두 딕셔너리를 병합하려면?

파이썬 3.9+에서는 | 연산자를 사용하세요: merged = dict_a | dict_b. 이전 버전에서는 {**dict_a, **dict_b}를 사용하세요.

*args와 **kwargs의 차이는 무엇인가요?

*args는 추가 위치 인자를 튜플로 모읍니다. **kwargs는 추가 키워드 인자를 딕셔너리로 모읍니다. 핵심은 단어가 아니라 *** 연산자에 있습니다. 이름은 무엇이든 쓸 수 있습니다.

파이썬에서 리스트가 비었는지 어떻게 확인하나요?

not 연산자를 사용하세요: if not my_list:. len(my_list) == 0을 확인하는 것보다 더 파이썬답습니다.

리스트 컴프리헨션과 제너레이터의 차이는?

리스트 컴프리헨션(대괄호)은 전체 리스트를 한 번에 메모리에 생성합니다. 제너레이터(소괄호)는 값을 하나씩 필요할 때 생성하므로, 큰 시퀀스에서 훨씬 적은 메모리를 사용합니다.

삼항 연산자는 언제 쓰면 좋나요?

양쪽 결과가 짧고 명확한, 단순한 한 줄 조건에 사용하세요: name = "John" if condition else "Doe". 더 복잡하다면 일반 if/else 블록이 더 읽기 쉽습니다.

리스트의 중복을 가장 쉽게 제거하는 방법은?

set()으로 감싸고 다시 변환하세요: list(set(my_list)). 단, 집합은 순서가 없으므로 원래 순서는 보존되지 않습니다.

주제

Top Python Courses

courses

중급 Python

4
1.4M
Matplotlib으로 시각화를 만들고 pandas로 DataFrame을 다루며 데이터 과학 역량을 높이세요.
자세히 보기Right Arrow
강좌 시작
더 보기Right Arrow