zip과 *, **을 이용한 언패킹(unpacking)

개발공부를해보자·2025년 1월 19일

공부 정리

목록 보기
14/32
  • zip은 여러 iterable한 객체를 하나로 묶어 tuple의 리스트를 생성
  • *iterablelist, tuple 의 요소를 개별 인수로 풀어서 전달
  • **dictionarykey:value를 개별 인수로 풀어서 전달
# zip() 함수 사용법과 예시
# zip은 여러 개의 반복 가능한 객체를 하나로 묶어 튜플의 리스트를 생성

# 1. 기본 사용법: 여러 리스트의 요소를 묶기
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
countries = ['USA', 'UK', 'Canada']

zipped_data = list(zip(names, ages, countries))
print(zipped_data)
# 출력: [('Alice', 25, 'USA'), ('Bob', 30, 'UK'), ('Charlie', 35, 'Canada')]

# 2. 반복문에서의 활용
for name, age, country in zip(names, ages, countries):
    print(f'{name} is {age} years old and lives in {country}.')

# 3. 최소 길이 기준으로 동작
list1 = [1, 2, 3]
list2 = ['a', 'b']
zipped_short = list(zip(list1, list2))
print(zipped_short)
# 출력: [(1, 'a'), (2, 'b')] (길이가 짧은 리스트 기준으로 묶임)

# 4. zip(*iterables)로 언패킹
zipped = zip(names, ages)
names_unpacked, ages_unpacked = zip(*zipped)
print(names_unpacked)  # ('Alice', 'Bob', 'Charlie')
print(ages_unpacked)   # (25, 30, 35)

# 5. 딕셔너리로 변환
keys = ['name', 'age', 'country']
values = ['Alice', 25, 'USA']
person_dict = dict(zip(keys, values))
print(person_dict)
# 출력: {'name': 'Alice', 'age': 25, 'country': 'USA'}

# 6. zip()에 인수가 한 개일 경우
single_list = ['apple', 'banana', 'cherry']
zipped_single = list(zip(single_list))
print(zipped_single)
# 출력: [('apple',), ('banana',), ('cherry',)] (튜플 형태로 반환됨)

# 7. 인덱스와 함께 zip 사용
for index, (name, age) in enumerate(zip(names, ages)):
    print(f'Index {index}: {name}, {age}')

# --------------------------------------------
# *와 **를 이용한 언패킹 (Unpacking)
# * (asterisk)는 리스트/튜플을 개별 요소로 풀어서 함수에 전달하는 데 사용
# **는 딕셔너리를 키워드 인수로 언패킹하는 데 사용

# 8. 리스트에서 *를 이용한 언패킹
numbers = [1, 2, 3, 4, 5]
first, *middle, last = numbers
print(first)   # 1
print(middle)  # [2, 3, 4]
print(last)    # 5

# 9. 함수 인자 전달 시 *를 사용한 리스트 언패킹
def add_numbers(a, b, c):
    return a + b + c

num_list = [1, 2, 3]
result = add_numbers(*num_list)
print(result)  # 6

# 10. **를 사용한 딕셔너리 언패킹
def show_info(name, age, country):
    print(f'Name: {name}, Age: {age}, Country: {country}')

person_info = {'name': 'Alice', 'age': 25, 'country': 'USA'}
show_info(**person_info)
# 출력: Name: Alice, Age: 25, Country: USA

# 11. 함수 정의에서 가변 인자 (*args, **kwargs)
def print_info(*args, **kwargs):
    print("Positional arguments:", args)
    print("Keyword arguments:", kwargs)

print_info(1, 2, 3, name='Bob', age=30)
# 출력:
# Positional arguments: (1, 2, 3)
# Keyword arguments: {'name': 'Bob', 'age': 30}

# 12. 리스트 결합 및 확장
list_a = [1, 2, 3]
list_b = [4, 5, 6]
combined_list = [*list_a, *list_b]
print(combined_list)
# 출력: [1, 2, 3, 4, 5, 6]

# 13. 딕셔너리 병합
dict_a = {'a': 1, 'b': 2}
dict_b = {'c': 3, 'd': 4}
merged_dict = {**dict_a, **dict_b}
print(merged_dict)
# 출력: {'a': 1, 'b': 2, 'c': 3, 'd': 4}

# 14. *을 이용한 딕셔너리 key 언패킹
my_dict = {'a': 1, 'b': 2, 'c': 3}
keys_list = [*my_dict]
print(keys_list)  
# 출력: ['a', 'b', 'c']

# --------------------------------------------
# 파이썬 알고리즘 인터뷰 31번(리트코드 347번) 풀이

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        count = collections.Counter(nums)
        return list(zip(*count.most_common(k)))[0]

# 코드 설명:
# 1. `collections.Counter(nums)`
#    - `nums` 리스트의 요소 빈도수를 계산하여 딕셔너리 형태로 반환.
#    - 예: nums = [1,1,1,2,2,3] -> Counter({1: 3, 2: 2, 3: 1})

# 2. `count.most_common(k)`
#    - 가장 빈도수가 높은 k개의 요소를 튜플 리스트 형태로 반환.
#    - 예: count.most_common(2) -> [(1, 3), (2, 2)] (숫자와 빈도수의 쌍)

# 3. `zip(*count.most_common(k))`
#    - 리스트를 여러 개의 튜플에서 개별 요소들의 튜플로 분리.
#    - 예: [(1, 3), (2, 2)] -> (1, 2), (3, 2)

# 4. `list(zip(*count.most_common(k)))[0]`
#    - 첫 번째 요소(숫자들)만 추출하여 리스트로 변환.
#    - 결과: [1, 2] (가장 빈도수가 높은 숫자 리스트 반환)

# `*`를 사용하지 않았다면?
# list(zip(count.most_common(k))) -> [((1, 3),), ((2, 2),)]
profile
개발 공부하는 30대 비전공자 직장인

0개의 댓글