키콤백신 개발 이야기 - 파이썬의 기본문법 (리스트, 딕셔너리, 튜플)

읽기 전에
Creative Commons License
본 내용은 키콤백신을 개발하면서 고민했던 내용들을 적은 것입니다. 따라서 다분히 개인적인 의견들이므로 보시는 분들에 따라서 이견을 가지실 수 있습니다. 그냥 "이 사람은 이렇게 개발하는구나" 하고 봐 주시면 좋겠습니다.

1. 들어가며

키콤백신의 소스 코드를 이해하기 위해서는 파이썬을 기본적으로 알아야 한다. 그래서 이전 문서에서 파이썬의 기본 문법1인 변수, 숫자, 문자열에 대해 알아보았다. 이번 문서에서는 파이썬의 자료구조에 대해서 알아보기로 한다.

2. 리스트 (list)

파이썬에서 리스트는 C/C++ 언어에 비하면 배열과 유사하다. 리스트를 표현하기 위해서는 대괄호 “[]“로 표시할 수 있으며 입력된 값은 index 형태로 접근 가능하다.

>>> arr = [1, 2, 3, 4, 5]
>>> len(arr) # arr 변수에 저장된 요소의 개수를 의미한다.
5
>>> arr[0] # arr 변수의 리스트 요소 중 0번째 저장된 값을 확인한다.
1
>>> _

C/C++ 언어의 배열과 유사하여 위 예제는 별 어려움이 없을 것이다. 이미 이전 문서1에서 우리는 파이썬이 동적 프로토타이핑 언어임을 이야기 하였다. 따라서 arr은 정수만을 저장하는 것이 아니라 다양한 자료형을 저장할 수 있다.

>>> arr = [1, 2, 3, 4, 5, 'hello'] # 정수와 문자열을 동시에 저장할 수 있다.
>>> arr[5]
'hello'
>>> _

2.1 중첩 리스트

리스트 내부에서는 단순히 특정 하나의 자료형만을 저장하는 것이 아니라는 사실을 이미 확인하였다. 그렇다면 리스트 내부에 리스트를 넣을수 있을까?

>>> arr = [1, 2, 3, ['hello', 'world']] # 중첩 리스트 생성
>>> len(arr) # arr 리스트의 요소는 4개 저장되어 있다.
4
>>> arr[3] # 3번째 인덱스의 내용은 리스트이다.
['hello', 'world']
>>> arr[3][0] # 3번째 인덱스의 리스트에서 다시 0번째 인덱스를 확인한다.
'hello'
>>> _

예) 악성코드의 패턴을 리스트에 추가하기

# 악성코드 패턴 2개를 리스트에 추가한다.
# 리스트의 문자열은 "악성코드명:패턴 문자열 위치:패턴 문자열"을 뜻한다.
VirusDB = [             \
    'EICAR:0:X5O',      \
    'EICAR2:0:XYZ'      \
] 

2.2 리스트 함수

리스트는 다양한 함수를 제공하고 있다. 자료구조에서 리스트는 꽤 빈번하게 사용하므로 간단한 함수들은 기억해 두는 것이 좋다.

  • list.append()

리스트에 값을 추가한다.

>>> arr = [] # 빈 리스트를 생성한다.
>>> arr.append(1) # 리스트에 1을 추가한다.
>>> arr.append('hello') # 리스트에 'hello'를 추가한다.
>>> arr
[1, 'hello']
  • list.count()

리스트 내부의 특정 값이 몇개가 존재하는지 개수를 알려준다.

>>> arr = [1, 2, 3, 1, 1] 
>>> arr.count(1) # 리스트 내부의 1의 개수를 체크한다.
3
>>> arr.count(2) # 리스트 내부의 2의 개수를 체크한다.
1
  • list.index()

리스트 내부의 특정 값이 몇번째 요소인지를 알려준다.

>>> arr = [1, 2, 3, 1, 1] 
>>> arr.index(1) # 리스트 내부에서 좌측부터 최초로 발견된 요소의 위치를 알려준다.
0
>>> arr.index(3)
2
  • list.insert()

리스트 내부에서 특정한 위치에 특정한 값을 삽입한다.

>>> arr = [1, 2, 3, 1, 1] 
>>> arr.insert(1, 'hello') # 1번째 인덱스 위치에 'hello'를 삽입한다.
>>> arr
[1, 'hello', 2, 3, 1, 1]
  • list.pop()

리스트 내부 값을 추출한다.

>>> arr = [1, 2, 3, 1, 1] 
>>> arr.pop() # 리스트에서 오른쪽부터 값을 추출한다.
1
>>> arr
[1, 2, 3, 1]
>>> arr.pop()
1
>>> arr
[1, 2, 3]
>>> arr.pop(0) # pop 함수의 인자값으로 특정 위치의 값을 추출도 가능하다.
1
>>> arr
[2, 3]
  • list.reverse()

리스트 내부의 각 요소들을 거꾸로 정렬한다.

>>> arr = [1, 2, 3, 1, 1] 
>>> arr.reverse() # 내부 요소들을 거꾸로 정렬한다.
>>> arr
[1, 1, 3, 2, 1]
  • list.sort()

리스트 내부의 각 요소들을 오름차순으로 정렬한다.

>>> arr = [1, 2, 3, 1, 1] 
>>> arr.sort() # 내부 요소들을 오름차순으로 정렬한다.
>>> arr
[1, 1, 1, 2, 3]

3. 딕셔너리 (dictionary)

사람이라는 객체에 대한 정보를 리스트로 구축했다고 가정해보자.

# 홍길동씨는 65세로 키 175cm, 몸무게 70kg이다. 
person = ['홍길동', 65, 175, 70] 

하지만 시간이 지나면 person에 저장한 값의 순서가 기억나지 않을 수도 있다. 즉, 나이와 몸무게를 바꾸어 생각할 수도 있다는 의미이다. 따라서 이를 혼란스럽게 하지 않기 위해서 파이썬의 딕셔너리 자료 구조에 데이터를 저장하는 것이 좋다. 파이썬에서 딕셔너리를 표현하기 위해서는 중괄호 “{}“를 사용한다.

>>> person = {} # 빈 딕셔너리를 선언한다.
>>> person['name'] = '홍길동'
>>> person['age'] = 65
>>> person['height'] = 175
>>> person['weight'] = 70 
>>> person
{'age': 65, 'name': '홍길동', 'weight': 70, 'height': 175}
>>> _

딕셔너리를 이용하여 객체의 자료를 저장해 두었다면 나중에 이 데이터에 접근할 때에는 혼란스러울 필요가 없다.

>>> person['age'] # 나이를 알고 싶다.
65
>>> person['weight'] # 몸무게를 알고 싶다.
70
>>> _

위의 예에서 ageweight은 Key라고 하며, 65, 70은 Value라고 한다.

예) 백신의 제작자와 어떤 용도의 백신인지 정보를 기록하기

vaccine_info = {}

vaccine_info['author'] = 'Kei CHoi'
vaccine_info['description'] = 'Vaccine for EICAR'

2.1 딕셔너리 함수

위에서 언급한 person 변수를 이용하여 아래의 함수들을 사용한 예이다.

  • dict.has_key()

딕셔너리가 해당 Key를 가지고 있는지 여부를 알려준다.

>>> person.has_key('name') # '이름'에 대한 정보가 있는가?
True
>>> person.has_key('address') # '주소'에 대한 정보가 있는가?
False
  • dict.items()

딕셔너리에 저장된 데이터를 리스트 형태로 변환한다.

>>> person.items()
[('age', 65), ('name', 'test'), ('weight', 65), ('height', 175)]
  • dict.keys()

딕셔너리에 저장된 데이터의 Key를 리스트 형태로 변환한다.

>>> person.keys()
['age', 'name', 'weight', 'height']
  • dict.values()

딕셔너리에 저장된 데이터의 Value를 리스트 형태로 변환한다.

>>> person.values()
[65, 'test', 65, 175]
  • dict.update()

딕셔너리에 저장된 데이터에 새로운 Key와 Value를 추가한다.

>>> temp = {} # 새로운 딕셔너리를 선언한다.
>>> temp['address'] = 'Seoul' # '주소' 정보를 입력한다.
>>>
>>> person.update(temp) # '주소' 정보를 반영한다.
>>> person
{'age': 65, 'address': 'Seoul', 'name': 'test', 'weight': 65, 'height': 175}
  • dict.pop()

딕셔너리에서 해당 Key의 정보를 추출한다.

>>> person
{'age': 65, 'address': 'Seoul', 'name': 'test', 'weight': 65, 'height': 175}
>>> person.pop('height') # '몸무게' 정보를 추출한다.
175
>>> person
{'age': 65, 'address': 'Seoul', 'name': 'test', 'weight': 65}

4. 튜플 (tupple)

파이썬에서 튜플은 리스트와 달리 값을 변화 시킬 수 없는 독특한 형태의 자료 구조이다. 튜플은 괄호 “()“로 표시한다.

>>> test = (1, 2, 3, 4, 5)
>>> len(test)
5
>>> test[0]
1
>>> _

위의 예제만 보면 리스트와 차이점이 없어 보인다. 하지만 값의 변화가 되지 않는 점이 큰 차이점이다.

>>> test1 = [1, 2, 3, 4, 5]
>>> test2 = (1, 2, 3, 4, 5)
>>>
>>> test1[4] = 'hello'
>>> test1
[1, 2, 3, 4, 'hello']
>>>
>>> test2[4] = 'hello'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> _

예제에서 볼 수 있듯이 값을 변화 시킬 수 없기 때문에 파이썬의 함수 리턴 값 및 인자 값을 처리할 때 사용하면 좋다. 중간에 값이 바뀔 일은 없으니까 안전하게 처리할 수 있다. 이는 향후 함수에서 자세히 다루기로 한다.

4.1 튜플 함수

  • tupple.count()

튜플 내부의 특정 값이 몇개가 존재하는지 개수를 알려준다.

>>> test = (1, 2, 3, 1, 1) 
>>> test.count(1) # 튜플 내부의 1의 개수를 체크한다.
3
>>> test.count(2) # 튜플 내부의 2의 개수를 체크한다.
1
  • tupple.index()

튜플 내부의 특정 값이 몇번째 요소인지를 알려준다.

>>> test = (1, 2, 3, 1, 1) 
>>> test.index(1) # 튜플 내부에서 좌측부터 최초로 발견된 요소의 위치를 알려준다.
0
>>> test.count(3)
2

5. 결론

변수, 숫자, 문자열에 이어 파이썬에서 다루는 대표적인 자료 구조인 리스트(list), 딕셔너리(dictionary), 튜플(tupple)에 대해서 알아보았다. 다음에는 파이썬의 제어 구조에 대해서 살펴보기로 한다.


Update

  • 2015-09-28 : 최초로 작성


크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 국제 라이선스에 따라 이용할 수 있습니다.