초보 개발자

14강 dict의 루핑 기술과 컴프리헨션 본문

Python/윤성우 열혈 파이썬

14강 dict의 루핑 기술과 컴프리헨션

taehyeki 2021. 12. 22. 15:57

[딕셔너리 루핑 테크닉]

딕셔너리를 대상으로 하는 가장 보편적인 for루프 구성은 다음과 같다.

d = dict(a=1,b=2,c=3)
for k in d: #k에는 키가 담긴다.
	print(d[k], enc=', ')

 

근데 아래와 같은 메소드를 알아두면 for 루프를 구성할 때 좀 더 효율적으로 코드를 작성할 수가 있다.

dict.keys() 딕셔너리의 키들만 참조하고자 할 때
dict.values() 딕셔너리의 값들만 참조하고자 할 때
dict.items() 딕셔너리의 키와 값을 튜플 형태로 참조하고자 할 때

위의 세 메소드가 반환하는 것을 가리켜 뷰 객체라고 한다. 뷰 객체도 iterable객체로 다음과 같이 for 루프를 통해 그 값을 하나씩 참조할 수 있다. 다음은 keys 메소드를 사용한 예이다.

 

dictionary에서 위의 메소드 들 중 하나라도 호출을 하면 뷰 객체가 생성이 되고 뷰 객체는 그 dictonary를 바라보고 있다.  그래서 dictionary의 상태를 잘 안다. 그리고 뷰 객체는 iterable객체이다. 따라서 우리가 요청을 하면 우리한테 iterator객체를 준다 우리는 그 iterator(리모콘)을 통해서 dictionary에 직접적인 접근은 불가하지만 뷰 객체를 통해서 dictionary에 접근할 수 있다. 그래서 무언갈 얻어다가 가져다 주는 형식이다.

 

즉 우리가 뷰에게 요청하면 알아서 뷰는 적절한 자료를 가져다 준다.

keys메소드

d = dict(a=1,b=2,c=3)
for k in d.keys(): # keys는 뷰 객체 반환한다. 즉 뷰 객체 이용한 for 루프이다.
	print(k, end = ', ') # 키가 순서대로 출력된다.
    
a, b, c,

values메소드

d = dict(a=1,b=2,c=3)
for v in d.values(): # values는 뷰 객체 반환한다. 즉 뷰 객체 이용한 for 루프이다.
	print(v, end = ', ') # 값이 순서대로 출력된다.
    
1, 2, 3,

items메소드

d = dict(a=1,b=2,c=3)
for kv in d.items(): # items는 뷰 객체 반환한다. 즉 뷰 객체 이용한 for 루프이다.
	print(kv, end = ', ') # (키, 값)이 순서대로 출력된다.
    
('a', 1), ('b', 2), ('c', 3),

for k,v in d.items(): # k와 v에 값을 저장하는 과정에서 튜플 언패킹
	print(k,v, end = ', ') 

a, 1
b, 2
c, 3

 

[뷰가 바라보는 현재 상태]

뷰 객체는 단순히 키 또는 값을 얻어오는데 사용될 뿐만 아니라 현재 딕셔너리의 상태를 그대로 반영한다는 특징이 있다. ('뷰'라는 이름처럼 딕셔너리의 현재 상태를 바라본다.)

d = dict(a=1,b=2,c=3)
vo = d.items() # 뷰 객체 얻음
for kv in vo:
	print(kv, enc = ' ')
    
('a', 1) ('b', 2) ('c', 3)

d['a'] += 3 #딕셔너리 수정
d['c'] -= 2 #딕셔너리 수정
for kv in vo: #수정 사항이 뷰 객체에 그대로 반영이 됨
	print(kv, end = ' ')
  
('a', 4) ('b, 2) ('c', 1)

수정이 된 것까지 반영된 것을 확인할 수 있다.

현재의 딕셔너리 상태를 바라보고 있다.!! 

 

 

[dict 컴프리헨션]

d1 = dict(a=1, b=2, c=3)
d2 = {k : v*2 for k, v in d1.items()} # d1의 값을 두 배 늘린 딕셔너리 생성
d3 = {k : v*2 for k, v in d2.items()} # d2의 값을 두 배 늘린 딕셔너리 생성

d1
{'a':1,'b':2,'c',3}
d2
{'a':2,'b':4,'c',6}
d3
{'a':4,'b':8,'c',12}

리스트컴퓨리헨션과 거의 흡사한 것을 알 수 있다.

 

물론 딕셔너리 컴프리헨션에도 리스트 컴프리헨션과 마찬가지로 if절을 추가할 수도 있다. 다음 예에서 보이듯이,

if절을 추가하는 기본적인 이유는 조건에 맞는 값들만 포함시키기 위함이다.

 

리스트 컴프리헨션

r1 = [1,2,3,4,5]
r2 = [x*2 for x in r1 if x % 2] #if절이 추가된 리스트 컴프리 헨션
r2
[2,6,10]

 

딕셔너리 컴프리헨션

d1 = dict(a=1,b=2,c=3,d=4)
d1
{'a':1,'b':2,'c':3,'d':4}
d2 = {k : v for k,v in d1.items() if v % 2} # d1에서 값이 홀수인 것만 모은 딕셔너리
d2
{'a':1,'c':3}

 

zip과 함께 사용한 예이다. 

두 리스트에 저장되어 있는 값들을 이용해서 딕셔너리를 생성하는 예제이다.

ks = ['a','b','c','d'] #이들은 키가 된다.
vs = [1,2,3,4] # 이들은 값이 된다.

{ k:v  for k,v  in zip(ks,vs) } # zip을 이용해서 같은 위치의 값들을 묶었다.
d
{'a':1, 'b':2, 'c':3,'d':4}

여기서 if절을 추가해서 홀수인 것만 남긴 예이다.

ks = ['a','b','c','d'] #이들은 키가 된다.
vs = [1,2,3,4] # 이들은 값이 된다.

{ k:v  for k,v  in zip(ks,vs) if v % 2}
d
{'a':1,'c':3}