[Python] 파이썬의 내장 함수

seon·2025년 4월 3일

Language

목록 보기
3/5
post-thumbnail

파이썬의 내장 함수

  • zip()
  • enumerate()
  • sorted(), sort()
  • bin()
  • insert(), pop()

다음은 파이썬 내장 함수들을 사용하는 방법을 잊지 않기 위한 개인적인 목적으로 그때그때 정리한 글입니다


2025.04.03

*️⃣ zip()

출처: https://www.daleseo.com/python-zip/

zip() 함수는 여러 개의 순회 가능한(iterable) 객체를 인자로 받고, 각 객체가 담고 있는 원소를 튜플의 형태로 차례로 접근할 수 있는 반복자(iterator)를 반환한다.

예시

>>> numbers = [1, 2, 3]
>>> letters = ["A", "B", "C"]
>>> for pair in zip(numbers, letters):
...		print(pair)
...
(1, 'A')
(2, 'B')
(3, 'C')

위 코드를 보면 numbers 리스트와 letters 리스트를 zip() 함수에 인자로 넘겨서 호출한 후에, for 문으로 zip() 함수의 반환값을 대상으로 루프를 돌면서 튜플을 차례로 출력하고 있다.
zip() 함수를 사용하지 않고, 인덱스(index) 변수를 사용해서 위 코드를 다시 작성해보면 좀 더 이해하기 쉽다고 한다.

>>> numbers = [1, 2, 3]
>>> letters = ["A", "B", "C"]
>>> for i in range(3):
...        pair = (numbers[i], letters[i])
...        print(pair)
...
(1, 'A')
(2, 'B')
(3, 'C')

위와 같이 zip() 함수를 사용하면 마치 옷의 지퍼를 올리는 것처럼 양 측에 있는 데이터를 하나씩 차례로 짝을 지어준다.

zip() 함수는 어떤 상황에서 유용하게 사용될 수 있는가?


병렬 처리

zip()함수를 활용하면 여러 그룹의 데이터를 루프를 한번만 돌면서 처리할 수 있다. 가변인자를 받기 때문에 2개 이상의 인자를 넘겨서 병렬 처리를 할 수 있다.

예를 들어, 아래 코드는 3개의 문자열 내의 글자를 하나씩 병렬해서 출력하고 있다.

>>> for number, upper, lower in zip("12345", "ABCDE", "abcde"):
...		print(number, upper, lower)
...
1 A a
2 B b
3 C c
4 D d
5 E e

튜플의 원소를 3개의 변수에 할당하기 위해서 for문에서 인자 풀기(unpacking)를 해주었다.


unzip

zip() 함수로 엮어 놓은 데이터를 다시 해체(unzip)하고 싶을 때도 zip() 함수를 사용할 수 있다.
먼저 zip() 함수로 2개의 튜플의 데이터를 엮은 후 리스트로 변환해보겠다.

>>> numbers = (1, 2, 3)
>>> letters = ("A", "B", "C")
>>> pairs = list(zip(numbers, letters))
>>> print(pairs)
[(1, 'A'), (2, 'B'), (3, 'C')]

이 리스트 앞에 풀기(unpacking) 연산자 붙여서 다시 zip() 함수에 넘기면 다시 원래의 2개의 튜플을 얻을 수 있다.

>>> numbers, letters = zip(*pairs)
>>> numbers
(1, 2, 3)
>>> letters
('A', 'B', 'C')

사전 변환

zip() 함수를 이용하면 두 개의 리스트나 튜플로부터 쉽게 사전(dictionary)을 만들 수 있다.
키를 담고 있는 리스트와 값을 담고 있는 리스트를 zip() 함수에 넘긴 후, 그 결과를 다시 dict() 함수에 넘기면 된다.

>>> keys = [1, 2, 3]
>>> values = ["A", "B", "C"]
>>> dict(zip(keys, values))
{1: 'A', 2: 'B', 3: 'C'}

dict() 함수에 키와 값으로 이루어진 튜플을 넘기면 사전이 생성되는 원리를 이용하는 것이다.
다른 예로, 날짜 데이터의 필드 이름 리스트와 필드 값 리스트를 사전으로 변환해보겠다.

>>> dict(zip(["year", "month", "date"], [2001, 1, 31]))
{'year': 2001, 'month': 1, 'date': 31}

주의 사항

zip() 함수로 넘기는 인자의 길이가 다를 때는 주의를 해야 한다. 왜냐하면 가장 짧은 인자를 기준으로 데이터가 엮이고, 나머지는 버려지기 때문이다.

>>> numbers = ["1", "2", "3"]
>>> letters = ["A"]
>>> list(zip(numbers, letters))
[('1', 'A')]

*️⃣ enumerate()

출처: https://www.daleseo.com/python-enumerate/

파이썬의 enumerate() 내장 함수로 for 루프 돌리기

많은 프로그래밍 언어들에서 i, j, k와 같은 소위 인덱스 변수를 증가시키면서 for 루프를 돌린다.
하지만 파이썬에서는 enumerate()라는 내장 함수를 통해
이러한 인덱스 변수를 사용하지 않고 루프를 돌리는 방식이 선호되며 이런 코딩 스타일을 소위 Pythonic, 즉 파이썬답다고 한다.


for 루프

>>> for letter in ['A', 'B', 'C']:
...		print(letter)
...
A
B
C

여기서 원소뿐만 아니라 인덱스도 함께 출력하고 싶을 때는 어떻게 해야 할까?

>>> i = 0
>>> for letter in ['A', 'B', 'C']:
...     print(i, letter)
...     i += 1
...
0 A
1 B
2 C

위 방법이 틀린 것은 아니지만, i 변수가 for 반복문이 종료된 이 후에도 네임 스페이스에 남아있기 때문에 이상적이지는 않다.
(네임 스페이스란? 내부 식별자(형식, 함수, 변수 등의 이름)에 범위를 제공하는 선언적 영역. )
또 다른 방법으로는 range()len() 내장 함수를 이용하여 만든 인덱스 목록을 대상으로 루프를 돌리는 것이다.

>>> letters = ['A', 'B', 'C']
>>> for i in range(len(letters)):
...     letter = letters[i]
...     print(i, letter)
...
0 A
1 B
2 C

이 방법은 이전 방법보다는 나아보이지만, 파이썬 커뮤니티에서는 이러한 코드를 소위 파이썬 답지(Pythonic) 않아 보인다고 한다.


enumerate() 함수

그럼 어떻게 해야 좀 더 파이썬답게 인덱스(index)와 원소를 동시에 접근하면서 루프를 돌릴 수가 있을까?
바로 파이썬의 내장 함수인 enumerate()를 이용하면 되는데, for 문의 in 뒷 부분을 enumerate() 함수로 한 번 감싸주기만 하면 된다.

>>> for entry in enumerate(['A', 'B', 'C']):
>>> 	print(entry)
...
...
(0, 'A')
(1, 'B')
(2, 'C')

enumerate() 함수는 기본적으로 인덱스와 원소로 이루어진 튜플을 만들어준다.
따라서 인덱스와 원소를 각각 다른 변수에 할당하고 싶다면 인자 풀기(unpacking)를 해줘야 한다.

>>> for i, letter in enumerate(['A', 'B', 'C']):
...		print(i, letter)
...
0 A
1 B
2 C

시작 인덱스 변경

루프를 돌리다보면 인덱스를 0이 아니라, 1로 시작하고 싶을 때가 있다. 이럴 때는 enumerate() 함수를 호출할 때 start 인자에 시작하고 싶은 숫자를 넘기면 된다.

>>> for i, letter in enumerate(['A', 'B', 'C'], start=1):
...		print(i, letter)
...
1 A
2 B
3 C
>>> for i, letter in enumerate(['A', 'B', 'C'], start=101):
...		print(i, letter)
...
101 A
102 B
103 C

enumerate() 원리

지금까지 for 문에서 enumerate() 함수를 사용하는 방법에 대해서 알아봤는데 enumerate() 함수 자체가 어떻게 작동하는지 좀 더 살펴보겠다.

파이썬에서 for 문은 내부적으로 in 뒤에 오는 목록을 대상으로 계속해서 next() 함수를 호출하고 있다고 생각할 수 있다. 따라서, 일반 리스트를 iter() 함수에 넘겨 반복자(iterator)로 만든 후 next() 함수를 호출해보면 원소들이 차례로 얻어지는 것을 알 수 있다.

>>> iter_letters = iter(['A', 'B', 'C'])
>>> next(iter_letters)
'A'
>>> next(iter_letters)
'B'
>>> next(iter_letters)
'C'

이번에는 enumerate() 함수를 호출한 결과를 대상으로 next() 함수를 계속해서 호출해보면, 인덱스와 원소의 쌍이 튜플(tuple)의 형태로 차례로 얻어지는 것을 알 수 있다.

>>> enumerate_letters = enumerate(['A', 'B', 'C'])
>>> next(enumerate_letters)
(0, 'A')
>>> next(enumerate_letters)
(1, 'B')
>>> next(enumerate_letters)
(2, 'C')

결국, enumerate() 함수는 인자로 넘어온 목록을 기준으로 인덱스와 원소를 차례대로 접근하게 해주는 반복자(iterator) 객체를 반환해주는 함수이다. 이 부분은 enumerate() 함수의 반환 값을 리스트로 변환해보면 좀 더 명확하게 확인할 수 있다.

>>> list(enumerate(['A', 'B', 'C']))
[(0, 'A'), (1, 'B'), (2, 'C')]

[Tip] 2차원 리스트 루프

이제 enumerate() 함수의 작동 원리까지 배웠으니 좀 더 고급 응용 사례를 살펴볼까? 아래와 같은 2차원 리스트나 튜플이 담고 있는 데이터를 루프를 돌면서 접근해야한다고 가정해보자.

>>> matrix = [['A', 'B', 'C'], ['D', 'E', 'F'], ['G', 'H', 'I']]

이 때 일반적으로 다음과 같이 중첩 for 문 내에서 행과 열의 인덱스로 데이터를 읽도록 작성을 많이 할거라고 한다.

>>> for r in range(len(matrix)):
...     for c in range(len(matrix[r])):
...             print(r, c, matrix[r][c])
...
0 0 A
0 1 B
0 2 C
1 0 D
1 1 E
1 2 F
2 0 G
2 1 H
2 2 I

동일한 작업을 하는 코드를 enumerate() 함수를 이용해서 재작성하면 어떨까?

>>> for r, row in enumerate(matrix):
...     for c, letter in enumerate(row):
...             print(r, c, letter)
...
0 0 A
0 1 B
0 2 C
1 0 D
1 1 E
1 2 F
2 0 G
2 1 H
2 2 I

코드가 더 깔끔하고 읽기 편하다!

예제 코드에서는 단순히 데이터를 출력만 하기 때문에 큰 차이를 못 느낄 수도 있지만, 실제 프로젝트에서 좀 더 복잡한 작업을 하는 경우라면 차이가 더 크게 날 것이다. 무엇보다도 2차원 배열을 다룰 때 인덱스를 사용하면 오타를 내기 쉬운데, enumerate() 함수를 사용하면 이러한 실수를 할 확률이 현저하게 줄어든다고 한다.


*️⃣ sorted(), sort()

출처: [파이썬] sort(), sorted() 완벽정리

sorted()

새로운 정렬된 리스트를 만든다.

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

원본 리스트는 바뀌지 않는다 - a에 sorted를 사용했을 때 a는 바뀌지 않는다.


sort()

기존의 리스트를 정렬한다.
리스트 내에서만 정의될 수 있다.

a = [5, 4, 3, 2, 1]
a.sort()
print(a) # [1, 2, 3, 4, 5]

key 매개변수

# a는 list
sorted(a, key)
a.sort(key)

오름차순, 내림차순 정렬

# a는 list
sorted(a, key, reverse=True) # 내림차순
sorted(a, key, reverse=False) # 오름차순

2차원 배열의 정렬

# 행 기준 정렬
list = [[1,2],[1,3],[0,5],[5,1],[4,3]] 
sorted(list, key = lambda x:x[0])
#[[0, 5], [1, 2], [1, 3], [4, 3], [5, 1]]

# 열 기준 정렬
sorted(list, key = lambda x:x[1])
#[[5, 1], [1, 2], [1, 3], [4, 3], [0, 5]]

# 다중 조건 정렬
sorted(list, key = lambda x: (x[1], x[0])) # 두번째 값이 같을 경우 첫번째 값을 기준으로 오름차순 
#[[5, 1], [1, 2], [1, 3], [4, 3], [0, 5]]
sorted(list, key = lambda x : (-x[0], x[1])) # 첫번째 값은 내림차순, 두번째 값은 오름차순
#[[5, 1], [4, 3], [1, 2], [1, 3], [0, 5]]
sorted(list, key = lambda x:-x[0]) # 첫번째 값을 내림차순
#[[5, 1], [4, 3], [1, 2], [1, 3], [0, 5]]


2025.04.07

*️⃣ bin()

출처: 파이썬에서 Int를 바이너리로 변환하는 방법

Python에서는 내장 함수 bin()을 사용하여 정수를 이진수로 변환 할 수 있습니다. bin()함수는 매개 변수로 정수를 취하고 0b 접두사가 붙은 동등한 바이너리 문자열을 반환합니다.

binary = bin(16)
print(binary)

출력:

0b10000

Python에서 format 함수를 사용하여 Int를 바이너리로 변환하는 방법

위와 같이 bin(x) 메소드로 간단히 정수의 이진수를 얻을 수 있습니다. 그러나 출력에서 0b 접두사를 제거하려면 format함수를 사용하여 출력 형식을 지정할 수 있습니다.

format(value, format_spec) 함수에는 valueformat_spec의 두 가지 매개 변수가 있습니다. format_spec에 따라 형식화 된 출력을 반환합니다. 다음은 자리 표시 자 내에서 사용할 수 있는 몇 가지 형식 지정 유형의 예입니다.

형식화 유형역할
=기호를 가장 왼쪽에 놓습니다.
b값을 동등한 바이너리로 변환합니다.
o값을 8 진수 형식으로 변환합니다.
x값을 16 진수 형식으로 변환
d주어진 값을 십진수로 변환합니다.
E대문자에 E가있는 과학적 형식
X값을 대문자의 16 진수 형식으로 변환합니다.

그리고 더 많은 포맷 유형을 사용할 수 있습니다. int를 바이너리로 변환하고 싶기 때문에 b 형식화 유형이 사용됩니다.

다음은 코드 예제입니다.

temp = format(10, "b")
print(temp)

출력:

1010

*️⃣ insert(), pop()

출처: 리스트(List)와 리스트 메소드(append, insert, remove, pop, extend)


list.insert(a,b) - 리스트의 특정위치에 값 추가

a = [1, 2, 3]
a.insert(0, 0)
print(a)

# [0, 1, 2, 3]

list.pop() - 리스트 맨 마지막 값 반환 후 삭제

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

# [1, 2, 3, 4]
# [5]

b = a.pop()에서 a의 마지막 요소를 b에 반환 후 a에서 해당값을 삭제한다.

profile
🌻

0개의 댓글