필자는 코드를 짜면서 유틸들을 자주 만들었다. 그러나 이것들은 로직이 복잡하지 않을 경우 지양해야 하는 방법이다. PYTHON을 사용한다면 최대한 PYTHONIC하게 구현하는 것을 지향해야 한다. 오늘은 내장함수인 zip()에 대해서 알아볼 것이다. 일단 필자의 전례를 들자면..
class StructureUtils:
@staticmethod
def mapping_dict_between_tuple(d: dict, t: tuple):
for i, key in enumerate(d):
d[key] = t[i]
return d
딕셔너리에 여러값을 담고 있는 iterator(여기서는 튜플)를 value에 자동으로 대입하고 싶었다. 그러나 하나하나 일일이 대입하기에 한계를 느껴 다음과 같은 유틸을 만들었다. 만들면서도 이런 기능을 할 수 있는 무언가가 있지 않을까? 라고 고민을 많이 했지만 당시에는 떠오르지 않았다. 하지만 우연히 zip() 이라는 내장함수를 알게되었다. zip의 예시를 들어보자.
a = ['a', 'b', 'c']
b = [1, 2, 3]
zip(a, b)
>> <zip object at 0x000001C29CBE3AC8>
다음과 같이 두 iterator를 zip하면 zip 인스턴스가 나온다.
for pair in list(zip(a, b)):
print(pair)
>>
('a', 1)
('b', 2)
('c', 3)
zip 인스턴스를 list로 캐스팅하고 for loop를 돌린 결과 다음과 같이 두 iterator의 데이터가 각각 쌍을 맺은 것을 확인할 수 있다.
for n, u, l in zip('123', 'ABC', 'abc'):
print(n, u, l)
>>
1 A a
2 B b
3 C c
다음과 같이 여러 iterator들의 원소들을 압축하여 for loop를 돌려 병렬처리 또한 가능하다.
pairs = list(zip(a, b))
pairs
>>
[('a', 1), ('b', 2), ('c', 3)]
a, b = zip(*pairs)
a
>>
('a', 'b', 'c')
b
>>
(1, 2, 3)
zip() 메소드의 인자로 *을 붙이면 unzip이 가능하다. 원리를 알아보자.
pairs
>>
[('a', 1), ('b', 2), ('c', 3)]
def f(args1=None, args2=None):
print(args1, args2)
l = [('a', 1), ('b', 2)]
f(*l) # *을 붙이면 각 요소가 함수의 인자로 전달된다. args1=('a', 1) args2=('b', 2)
zip(*pairs) # 이 부분의 인자는 arg1=('a', 1) arg2=('b', 2) arg3=('c', 3) 총 세개가 전달됬을 것이다.
# 위에서 본 병렬처리처럼
# arg1, arg2, arg3의 첫번째 요소가 묶여서 ('a', 'b', 'c')
# arg1, arg2, arg3의 첫번째 요소가 묶여서 (1, 2, 3)
list(zip(*pairs)) # [('a', 'b', 'c'), (1, 2, 3)]
a, b = list(zip(*pairs)) # a=('a', 'b', 'c') b=(1, 2, 3)
최종적으로 필자는 zip을 다음과 같이 활용했다.
overshoot = OrderedDict({'is_over': False, 'is_multi': False, 'intersection': None})
undershoot = OrderedDict({'is_under': False, 'start_geom': None, 'end_geom': None})
o = self._is_overshoot(layer_feature, line_feature)
u = self._is_undershoot(layer_feature, line_feature)
overshoot = dict(zip(overshoot.keys(), o))
undershoot = dict(zip(undershoot.keys(), u))
딕셔너리의 키(iterator 1)와 튜플(iterator 2)를 zip하여 dict로 캐스팅하면 key, value로 쌍이 맺어진다.
'[Language] - Python' 카테고리의 다른 글
#9. lambda, map, reduce, filter (0) | 2021.03.25 |
---|---|
#8. [Tip] if, 삼항연산자가 사용하기 싫을 때 (0) | 2021.03.24 |
#6. property 데코레이터 (8) | 2021.02.02 |
#5. 덕 타이핑 (Duck Typing) (2) | 2020.12.29 |
#4. 추상 클래스 (Abstract Class) (0) | 2020.12.28 |
댓글