# Comprehension

 


 

1. list comprehension

 

파이썬에서 for문은 사용할 수 있는 범위가 굉장히 넓습니다. 예를 들어 리스트를 하나 만들고 그 안에 값을 동적으로 추가해야 하는 상황이라면 아래와 같은 방법을 이용할 수 있겠죠.

myList = []

for i in range(10):
	myList.append(i) # [0,1,2,3,4,5,6,7,8,9]

 

만약에 리스트에 값을 삽입하는 규칙이 있다면, 리스트를 선언하면서 값을 삽입 할 수 있으면 편하지 않을까요? 파이썬에서는 이를 Comprehension이라고 하고 리스트나 딕셔너리에 적용하는 것이 가능합니다.

 

myList = [i for i in range(10)] # [0,1,2,3,4,5,6,7,8,9]

 

위의 코드가 바로 list comprehension 입니다. 리스트를 선언함과 동시에 리스트 안에 for 문을 넣어 요소를 저장하는 방법인데요 for 문의 i가 늘어남과 동시에 i의 값이 저장되는 모습입니다. 즉 가장 앞에 명시한 변수에 저장된 값이 반복문이 실행되면서 리스트의 요소로써 저장되는 것입니다.

 

만약 list comprehension에 for문만 사용이 가능하다고 한다면 의미가 없는 구문일 수 있습니다. 역시 파이썬 제작자는 이를 간파하고 if else등의 제어문도 사용할 수 있게 만들었습니다.

 

#if
myList = [i for i in range(10) if i%2==0] # [0,2,4,6,8]

#if else
myList = [i if i%2==0 else i-1 for i in range(10)] # [0,0,2,2,4,4,6,6,8,]

#nested loop
myList = [j for i in range(3) for j in range(3)] # [0,1,2,0,1,2,0,1,2]

위 의 코드를 보면 if 와 if - else를 쓸 때의 문법의 차이가 있다는 것을 느끼셨을 텐데요, if 는 for문 뒤에오는 반면 if-else는 for 문 전에 옵니다. 그리고 if문은 조건문에 부합하는 요소만 저장하는 반면에 if-else는 조건문에 부합하지 않는 요소도 값을 변형시켜서 저장할 수 있습니다.(i-1)

 

list comprehension은 편리한 기능이지만, 이를 무분별하게 사용하는 것은 코드의 가독성을 해칩니다. 따라서 조건문이 다중이거나 nested된 반복문이라면 list comprehension을 지양하는 것이 좋습니다.

 


 

2. dictionary comprehension

 

사실 dictionary는 list 만큼 comprehension이 유용하지 않습니다. 하지만 길이가 같은 리스트 2개를 각각 Key Value로 삼아 딕셔너리로 형변환 하고자 한다면 유용하게 사용할 수 있습니다.

 

아래의 코드를 보시면 for문을 이용하여 길이가 같은 리스트 2개를 딕셔너리로 만드는 방법이 기재 되어있습니다. 기존의 코드는 리스트의 크기만큼 for문을 실행시켜서 딕셔너리에 각각의 Key, Value로 저장하는 방법인데요, 저는 개인적으로 Dictionary comprehension이 코드의 길이도 짧고 특정상황에서는 훨씬 가독성이 좋다고 생각합니다.

myList_1 = [1,2,3]
myList_2 = ['a','b','c']

# original code
newDict = dict()
for i in range(len(myList_1)):
    newdict[myList_1[i]] = myList_2[i]

# dictionary comprehension
newDict = {myList_1[i]: myList_2[i] for i in range(len(myList_1))}

 

Dictionary comprehension은 dictionary의 Key-Value를 반전시키는데도 사용할 수 있습니다. dictionary class의 메소드로 제공되고 있는 items()는 dictionary의 모든 key,value쌍을 tuple로 상속된 객체를 리턴합니다. 해당 객체는 iteration 클래스이기 때문에 for문의 iterable 객체로 사용할 수 있습니다. 그렇기 때문에 다음과 같은 방식을 이용하면 dictionary  Key-Value를 반전 시킬 수 있습니다.

 

# original code
myDict = {1: 'a', 2: 'b', 3: 'c'}
newDict = dict()
for key,value in myDict.items():
    newDict[value] = key

# dictionary comprehension
myDict = {1: 'a', 2: 'b', 3: 'c'}
newDict = {value : key for key,value in myDict.items()}

 

 


 

3. zip함수를 이용한 자료형 변환

 

파이썬에서 기본으로 제공하고 있는 zip함수는 리스트를 딕셔너리로 변경해주거나 딕셔너리의 Key-Value를 반전시키는데 가장 효율적인 함수입니다. 

# List to dictionary
myList_1 = [1,2,3]
myList_2 = ['a','b','c']
newDict = dict(zip(myList_1,myList_2))

# Key-Value reverse
myDict = {1: 'a', 2: 'b', 3: 'c'}
reverse_dictionary = dict(zip(myDict.values(),myDict.keys()))

위 코드는 zip함수를 이용하여 list 2개를 dictionary로 변환시키는 코드입니다. Dictionary comprehension이나 일반적인 for문으로 변환 시키는것보다 코드의 길이도 짧고 가독성도 훌륭합니다. 

또한 마지막 라인을 보시면 zip함수를 이용하여 dictionary를 반전시켰습니다. dictionary class의 메소드인 values()와 keys()를 이용하여 모든 value와 key를 추출하고 zip함수의 첫 번째, 두 번째 인자로 넣습니다.

여기까지만 하면 zip 클래스의 인스턴스가 되게 됩니다. 이 객체는 Iterable하지만 dictionary라고 할 수 없죠, 그래서 전체 구문을 dict로 감싸 형변환을 마무리합니다.

 

 

'Dev > python' 카테고리의 다른 글

[python] 클래스(class)와 인스턴스  (1) 2019.04.07
[python] 함수  (0) 2019.04.04
[python] 제어문(if, for, while) - 3  (0) 2019.03.23
[python] 시퀀스 자료형과 이터러블  (1) 2019.03.23
[python] 제어문(if, for, while) - 2  (0) 2019.03.23

# 파이썬 딕셔너리



딕셔너리란 대응되는 데이터를 Key:Value 형식으로 저장할 수 있는 자료구조입니다. 타 언어에서는 연관배열이나 해시맵이라고 하죠?


딕셔너리는 리스트처럼 순차적으로 요소에 접근하는 시퀀스 자료형이 아닙니다. 반드시 Key를 통하여 Value값을 얻습니다. 예를 들어 language라는 KeyPython이라는 Value가 저장되어있을 경우 language를 통해 Python이라는 값을 얻을 수 있습니다.



1. 딕셔너리 선언


딕셔너리의 각 요소는 Key:Value 형태로 이루어져 있고 쉼표(",")로 데이터를 구분 짓습니다. 그리고 Key와 Value가 같은 자료형일 필요는 없습니다. Key가 문자열이고 Value가 숫자나 리스트나 딕셔너리여도 상관이 전혀 없습니다.

하지만 만약 중복되는 키를 입력시에는 데이터가 무시 되기 때문에 필수적으로 중복검사를 실시해야 합니다.


1
2
3
dic ={} # 빈 딕셔너리 선언
dic = dict() # 빈 딕셔너리 선언
dic = {"Key":"Value","number":1234#여러데이터 저장 가능
cs



2. 딕셔너리 값 추가 및 수정


딕셔너리의 값을 수정하기 위해서는 먼저 요소에 키를 통하여 접근할 필요가 있습니다. 만약 수정하려는 값의 key가 2일 경우에는 2로 접근하시면 됩니다.

값을 추가하고 싶은 경우에도 마찬가지입니다. 딕셔너리 이름이 dic일 경우에 dic["newKey"] 처럼 새로운 키를 설정해주고 값을 대입하면 됩니다. newKey라는 키는 제가 임의로 만든것이며 어떤 값이여도 상관없습니다. 


1
2
3
4
5
6
dic = {1:"a"}
dic[2= "b"
# dic == {1:"a",2:"b"}
 
dic[2= "c"
# dic == {1:"a",2:"c"}
cs



3. 딕셔너리 데이터 접근


리스트에서는 요소 값에 접근하기 위하여 인덱싱을 사용하였지만 딕셔너리는 인덱싱이아니라 Key이름을 기반으로 데이터에 접근합니다.


1
2
3
dic = {"apple":500,"banana":1000}
#dic["apple"] == 500
#dic["banana"] == 1000
cs



# 딕셔너리 내장함수



1. keys


딕셔너리 모든 Key를 객체로 리턴합니다. key만을 추출할 때 사용합니다.


1
2
3
4
dic = {"apple":500"banana":1000}
dic.keys()
 
#dict_keys(['apple', 'banana'])
cs



2. values


딕셔너리 모든 Value를 객체로 리턴합니다. Value만을 추출할 때 사용합니다.


1
2
3
4
dic = {"apple":500"banana":1000}
dic.values()
 
# dict_values([500, 1000])
cs


3. items


items 함수는 딕셔너리의 모든 데이터를 객체로 리턴합니다.


1
2
3
4
dic = {"apple":500"banana":1000}
dic.items()
 
# dict_items([('apple', 500), ('banana', 1000)])
cs


4. get


get함수는 키를 알고 있을 데 value를 추출할 때 사용합니다.


1
2
3
4
dic = {"apple":500"banana":1000}
dic.get("apple")
 
# 500
cs



'Dev > python' 카테고리의 다른 글

[python] 제어문(if, for, while) - 1  (0) 2019.02.15
[python] 튜플과 Immutable  (0) 2019.02.14
[python] 리스트 함수  (0) 2019.02.11
[python] 리스트와 Shallow Copy  (0) 2019.02.10
[python] 문자열 함수  (0) 2019.02.09

+ Recent posts