12장. 자료구조-[collections 모듈]

106180 단어 pythonpython

collections 모듈

파이썬의 내장 자료구조(built in data structure) 모듈인 collections은 앞의 리스트, 튜플, 딕셔너리 등을 확장하여 제작된 파이썬의 내장 모듈이다. 앞의 자료구조의 부족한 부분을 개선하였기에 보다 효율적이며 효과적이다.
collections 모듈은 deque, OrderedDict, defalutdict, Counter, namedtuple 등을 제공한다.

deque 모듈

deque(double-ended queue) 모듈은 스택과 큐를 모두 지원하는 모듈이다.
보통의 큐(queue)는 FIFO 방식으로, 스택(stack)은 FILO 방식이다. deque 모듈은 양방향을 지원한다. 즉 앞, 뒤에서 요소들의 추가, 제거가 가능하다.

deque 모듈은 메모리의 효율적 사용과 빠른속도라는 측면에서 유용하다. deque의 스택, 큐의 처리는 list에 비해 월등히 빠르다. 일반적인 리스트(list)가 이러한 연산에 O(n)이 소요되는 데 반해, 데크(deque)는 O(1)로 접근이 가능하다. 대용량의 큐, 스택을 처리할 일이 있다면 deque가 적합하다.

deque를 사용하기 위해서는 리스트와 비슷한 형식으로 데이터를 저장해야 한다. 기존의 리스트 처럼 append() 함수를 사용하여 데이터가 인덱스(index) 번호를 늘리면서 쌓이기 시작한다.

from collections import deque

deque_list = deque()
for i in range(5):
    deque_list.append(i)
print(deque_list)

출력 결과:
deque([0, 1, 2, 3, 4])

그리고 다음과 같이 .pop() 메서드를 작성하면, 오른쪽 요소부터 하나씩 추출된다. 즉 스택(stack)과 같이 늦게 들어간 값이 먼저 나온다.

만일 deque에서 큐(queue)를 구현하고자 한다면 .pop(0)를 작성하면 되는 것 처럼 보이지만 이는 작동하지 않는다. 이 때는 .appendleft() 메서드로 새로운 값을 왼쪽에서 받게한다. 하여 먼저 들어간 값이 먼저 나오게 하는 큐를 구현할 수 있다.(혹은 .popleft()을 작성해도 된다.)

from collections import deque

# 스택의 구현
deque_list = deque()
for i in range(5):
    deque_list.append(i)
print(deque_list)

for _ in range(5):
    print(deque_list.pop())

print('----------------')
# 큐의 구현
deque_list = deque()
for i in range(5):
    deque_list.appendleft(i)
print(deque_list)

for _ in range(5):
    print(deque_list.pop())

출력 결과:
deque([0, 1, 2, 3, 4])
4
3
2
1
0
----------------
deque([4, 3, 2, 1, 0])
0
1
2
3
4

deque의 매개변수로 maxlen이 있다. 이는 deque의 요소의 개수를 조정한다. 만일 append 함수를 통해 요소를 넣는다면 요소는 오른쪽으로 추가가 된다. 이 때 maxlen이 3이고 요소의 개수가 3을 넘는다면 왼쪽 부터 요소들이 삭제된다. 반대로 appendleft로 한다면 오른쪽에서 부터 요소가 삭제된다.

from collections import deque

test = deque('abc',maxlen=3)
print(test)
# 오른쪽에 요소가 추가된다
test.append(1)
print(test)
# 왼쪽에 요소가 삭제된다.
test.appendleft('A')
print(test)

deque.rotate() 메소드

deque 모듈은 기존 리스트와 비교하여 몇 가지 장점이 있다. 먼저 deque는 연결 리스트(Linked list)의 특성을 지원한다. 연결 리스트는 데이터를 저장할 때 요소의 값을 한 쪽으로 연결한 후, 요소의 다음 값의 주소값을 저장하여 데이터를 연결하는 기법이다. 간단히 말하면 데이터 요소를 저장할 때 그 다음 순서의 자료가 있는 위치를 데이터에 포함시키는 방식으로 자료를 저장한다.
예를 들어 1번 자료에 2번 자료의 위치를 저장하는 것이다.

연결 리스트는 아래의 그림처럼 다음 요소의 주소값을 저장하므로 데이터를 원형으로 저장할 수 있다. 또한 마지막 요소에 첫 번째 값의 주소를 저장한다면 해당 값으로 찾아갈 수 있다. 이러한 특징 때문에 가능한 기능 중 하나가 rotate() 메소드 이다. rotate()는 기존 deque에 저장된 요소들의 값 인덱스를 바꾸는 기법이다. 연결 리스트는 양쪽 끝의 요소들을 연결할 수 있으므로 원형의 데이터 구조를 가질 수 있다. 이러한 특징을 이용하여 각 요소의 인덱스 번호를 하나씩 옮긴다면 실제로 요소를 옮기지 않아도 인덱스 번호를 바꿀 수 있다.


rotate(n)은 요소들(elements)을 n값 만큼 회전 해주는 메소드이다. 만일 n 값이 음수(negative)라면 왼쪽으로, 양수라면 오른쪽으로 회전한다.

from collections import deque

deque_list = deque()
for i in range(5):
	deque_list.appendleft(i)
print(deque_list)
# 요소들을 오른쪽으로 2만큼 이동
deque_list.rotate(2)
print(deque_list)
# 요소들을 왼쪽으로  2 만큼 이동
deque_list.rotate(-2)
print(deque_list)


출력결과
deque([4, 3, 2, 1, 0])
deque([1, 0, 4, 3, 2])
deque([4, 3, 2, 1, 0])

deque 관련 메소드

함수설명
.append(item)item을 데크의 오른쪽 끝에 삽입한다.
.appendleft(item)item을 데크의 왼쪽 끝에 삽입한다.
.pop()데크의 오른쪽 끝 엘리먼트를 가져오는 동시에 데크에서 삭제한다.
.popleft()데크의 왼쪽 끝 엘리먼트를 가져오는 동시에 데크에서 삭제한다.
.extend(sequence)주어진 시퀀스 자료를 순회하면서 데크의 오른쪽에 추가한다.
.extendleft(sequence)주어진 시퀀스 자료를 순회하면서 데크의 왼쪽에 추가한다.
.remove(item)item을 데크에서 찾아 삭제한다.
.rotate(num)데크를 num만큼 회전한다.(양수면 오른쪽, 음수면 왼쪽).
.reversed(deque_list)deque의 요소들을 반대로 위치 시킨다. 각 요소들이 다른 주소를 알기에 가능하다.
from collections import deque

deque_list = deque()
# deque의 요소 생성
for i in range(5):
	deque_list.append(i)
print(deque_list)
# deque 요소들을 반대로 위치
print(deque(reversed(deque_list)))

# deque의 오른쪽에서 시퀀스 자료(문자열)를 넣고 있다.
deque_list.extend('hello')
print(deque_list)
# deque의 왼쪽에서 시퀀스 자료(리스트)를 넣고 있다.
deque_list.extendleft([5, 6, 7])
print(deque_list)

출력 결과:
deque([0, 1, 2, 3, 4])
deque([4, 3, 2, 1, 0])
deque([0, 1, 2, 3, 4, 'h', 'e', 'l', 'l', 'o'])
deque([7, 6, 5, 0, 1, 2, 3, 4, 'h', 'e', 'l', 'l', 'o'])

OrderedDict 모듈

OrderedDict 모듈은 이름에서 유추가 가능하드시 기존의 순서를 보장하지 않던 객체 딕셔너리(Dictionary)의 개선안이다.
(원래는 딕셔너리는 인덱스가 없기에 순서를 보장하지 않는다. 허나 파이썬 버전이 올라감에 따라 순서대로 출력되고 있다.)

OrderedDict는 키의 순서를 보장해준다. 가장 기본적인 방법은 입력한 순서대로 결과를 화면에 출력하는 것이다.

OrderedDict 모듈은 딕셔너리의 '순서대로 저장하지 않는 방식'을 '순서대로 저장하는 방식'으로 개선되었으며, 아울러 동등성 비교시에도 좀 더 이전 딕셔너리보다 더 꼼꼼하게 비교해주는 모듈로 보면 될 것이다.

즉 OrderedDict 를 사용 하면 정확한 데이터의 순서나 값을 유지하는데 일반 딕셔너리에 비해서는 우월하다.

from collections import OrderedDict # OrderedDict 모듈 선언
d = OrderedDict()
d['x'] = 100
d['y'] = 200
d['z'] = 300
d['l'] = 500

for k, v in d.items():
	print(k, v)
출력결과
x 100
y 200
z 300
l 500

ordereddict의 가장 많이 사용하는 경우는 딕셔너리로 데이터를 처리 할 때 키나 값으로 데이터를 정렬할 때이다. 예를 들어 키를 이용하여 주민등록번호를 번호 순서대로 정렬한 후, 데이터를 출력할 수 있다.

def sort_by_key(t):
	return t[0]
# t[0]는 튜플 값 중에서 0번 째 인덱스(a,b,d,c)를 말하며
# t[1]으로 한다면 1번 째 인덱스(100,200,300,500)을 뜻한다.
from collections import OrderedDict # OrderedDict 모듈 선언

d = dict()
d['a'] = 100
d['b'] = 200
d['d'] = 300
d['c'] = 500
for k, y in OrderedDict(sorted(d.items(), key= sort_by_key)).items():
	print(k, y)

출력 결과:
a 100
b 200
c 500
d 300

위의 코드의 결과는 딕셔너리의 값인 변수를 리스트 형태로 만든 다음, sorted( ) 함수를 사용하여 정렬한다. sorted(d.items(), key=sort_by_key)의 코드만 따로 실행하면 다음처럼 정렬되어 이차원 형태로 출력되는 값을 확인할 수 있다.

[('l', 500), ('x', 100), ('y', 200), ('z', 300)]

정리하면, 기존의 딕셔너리 항목들을 sorted()함수의 key를 기준으로 정렬하여 이를 리스트 형태로 반환한다. 그리고 다시 OrderDict 로 감싸주는 방식이다. 이렇게 하면 기존의 딕셔너리나 리스트의 순서를 지키면서 딕셔너리 형태로 관리할 수 있는 것이다.

OrderDict의 동등성 비교

아래의 딕셔너리의 경우 동등성을 비교할 때 주소와 순서가 비록 틀리더라도 '키:값' 의 항목들만 같으면 논리적 동등으로 인해 True가 출력됬다.

dic1 = {'A': 1, 'B': 2, 'C': 3}
dic2 = {'A': 1, 'C': 3, 'B': 2}
print(dic1 == dic2)
출력결과
True

하지만 OrderDict의 경우 데이터의 순서까지 고려한다.

from collections import OrderedDict
ordered_dic1 = OrderedDict({'A': 1, 'B': 2, 'C': 3})
ordered_dic2 = OrderedDict({'A': 1, 'C': 3, 'B': 2})
print(ordered_dic1 == ordered_dic2)

ordered_dic3 = OrderedDict({'A': 1, 'B': 2, 'C': 3})
print(ordered_dic1 == ordered_dic3)

출력결과
False
True

defaultdict 모듈

defaultdict 모듈은 딕셔너리의 요소를 생성할 때 키의 '값'에 기본 값을 지정하는 방법이다. 이를 통해 새로운 키를 생성할 때 그 키에 걸맞는 값을 넣지 않아도 기본 값이 들어간다.
딕셔너리에서는 키를 생성하지 않고 해당 키의 값을 호출하려고 할 때, 오류가 발생한다. 즉, 아래 코드에서 first의 키 값을 별도로 생성하지 않은 채 바로 호출하여 오류가 발생하였다.

# dictionary의 경우
d = dict()
print(d["first"])

출력결과:
Traceback (most recent call last):
File "defaultdict1.py", line 2, in <module>
print(d["first"])
KeyError: 'first'

# defaultdict의 경우
from collections import defaultdict

d = defaultdict(lambda: 0)          # default 값을 0으로 설정
print (d["first"])

출력결과:
0

위의 무명함수(람다함수)는 'lambda (인자) : (표현법)' 와 같은 문법으로 되어 간단히 함수를 호출하는 방법이다.
위의 코드에서 lambda : 0 은 defaultdict의 키에 해당하는 값을 기본적으로 0 으로 설정하겠다라는 것이다. 즉, 어떤 키가 들어오더라도 처음 값은 전부 0으로 설정한다는 뜻이다.

또 다른 것으로 defaultdict를 활용해 기본값에 'int'를 선언해주고, 기존에 없던 key를 호출하면 자동으로 0으로 초기화된다. 또한 미리 선언하지 않은 key에 해당하는 값에다가 값을 더하는 것도 가능하다.

from collections import defaultdict

d_dict = defaultdict(int)
# 아래를 통해 자동으로 0으로 초기화 됨을 확인 할 수 있다.
print(d_dict['a'])
d_dict['b'] += 10
print(d_dict['b'])

print(d_dict)

출력 결과:
0
10
defaultdict(<class 'int'>, {'a': 0, 'b': 10})

다음 함수는 defaultdict를 사용하지 않고 dictinary를 초기화 하는 코드이다.
아래 함수는 for 루프 안에 if 조건절을 통해서 counter 딕셔너리에 어떤 글자가 키(key)로 존재하지 않는 경우, 해당 키에 대한 기본값을 0으로 세팅해주고 있다.

def countLetters(word):
    counter = {}
    for letter in word:
        if letter not in counter:
            counter[letter] = 0
        counter[letter] += 1
    return counter     # 결과는 전부 1로 초기화가 이루어진다.

이러한 코딩 패턴은 파이썬에서 딕셔너리를 사용할 때 상당히 자주 접할 수 있다. 허나 이는 코드 가독성 측면에서 이러한 사소한 처리가 주요 흐름을 파악하는데 방해를 한다.
하여 좀 더 좋은 방법으로 딕셔너리의 dict.setdefalut() 함수를 사용할 수 있지만, 이 역시도 루프를 돌 때마다 함수가 호출되므로 조금 비효율적이다. 결국 defaultdict() 를 이용하면 이런 루프로 부터 딕셔너리의 기본값 처리 코드를 좀 더 효율적으로 기본값으로 초기화 할 수가 있다.

from collections import defaultdict

def countLetters(word):
    counter = defaultdict(int)
    for letter in word:
        counter[letter] += 1
    return counter

defaultdict의 초기값은 람다, int 외에 다음과 같이 리스트와 세트 형태로 설정할 수 있다.

from collections import defaultdict

s = [(‘Cyellow’, 1), (‘blue’, 2), (‘yellow’, 3), (‘blue’, 4), (‘red’, 1)]
d = defaultdict(list)
for k, v in s:
	d[k].append(v)
print(d.items())

출력결과:
dict_items([('Cyellow', [1]), ('blue', [2, 4]), ('yellow', [3]), ('red', [1])])

s 변수에 튜플 데이터를 2차원 형태로 저장하였다. d = defaultdict(list) 문장으로 초기값을 리스트로 선언한다.그 다음 모든 값이 리스트에 들어가 for문을 사용하여 새로운 값을 추가할 수 있다. 이렇게 하면 위의 s 변수처럼 같은 이름을 가진 여러 개의 키 key가 생긴다. defaultdict 모듈은 이런 키의 값들을 하나로 만들 때 사용할 수 있는 방법 중 하나다.


다음은 세트와 리스트를 이용하여 각 알파벳의 글자의 수를 세어서 저장하고 딕셔너리를 리턴하는 코드이다.

# 빈 list를 기본값으로
from collections import defaultdict

def groupWords(words):
    grouper = defaultdict(list)
    for word in words:
        length = len(word)
        grouper[length].append(word)
    return grouper
    
li1 = ["감자","귤","사과","배","오징어","꼼장어"]
dic2 = groupWords(li1)
print(dic2)

출력결과:
defaultdict(<class 'list'>, {2: ['감자', '사과'], 1: ['귤', '배'], 3: ['오징어', '꼼장어']})

# 빈 set를 기본값으로 
from collections import defaultdict

def groupWords(words):
    grouper = defaultdict(set)
    for word in words:
        length = len(word)
        grouper[length].add(word)
    return grouper
    
set1 = set()
set1.add("한국")	set1.add("중국")	set1.add("브라질")
set2 = groupWords(set1)
print(set2)

출력결과
defaultdict(<class 'set'>, {3: {'브라질'}, 2: {'한국', '중국'}})

counter 모듈

counter 모듈은 시퀀스 자료형의 데이터 값의 개수를 딕셔너리 형태로 반환하는 자료구조이다. 즉 문자열, 리스트 등의 시퀀스 자료형 안의 값 중 같은 것이 몇 개 있는 지를 반환한다.

from collections import Counter

text = list("gallahad"))
print(text)
c = Counter(text))
print(c)
print(c[“a”])

출력 결과:
[‘g’, ’a’, ’l’, ‘l’,  ‘a’, ‘h’, ‘a’, ‘d’]
Counter({'a': 3, 'l': 2, 'g': 1, h': 1, d': 1})
3

위 코드에서는 기존 문자열 값인 ‘gallahad'를 리스트형으로 변환한 후, text 변수에 저장하였다. c라는 Counter 객체를 생성하면서 text 변수를 초깃값으로 설정하고 이를 출력하면, 위 결과처럼 각 알파벳이 몇 개씩 있는지 쉽게 확인할 수 있다. c["a"]처럼 딕셔너리 형태의 문법을 그대로 이용해 특정 텍스트의 개수도 바로 출력할 수 있다.


counter()에는 '값 = 개수' 형태로 입력이 가능하다.
예를 들어 Counter(a=2, b=3, c=2)는 ['a','a','b','b','b','b','c','c'] 와 같다.

from collections import Counter

c = Counter(a=2, b=3, c=2)
print(c)
print(sorted(c.elements()))

출력 결과:
Counter({'b': 3, 'c': 2, 'a': 2})
['a', 'a', 'b', 'b', 'b', 'c', 'c']

위의 elements 메소드는 Counter로 주어진 값의 요소에 해당하는 값을 풀어서 반환한다.
요소는 무작위로 반환하며 sorted()를 통해 정렬할 수 있다. 대소문자를 구분하며 요소 수가 1보다 작을 경우 elements()는 이를 출력하지 않으며


앞에서 defalutdict를 사용하여 각 문자의 개수를 셌다. 허나 Counter를 이용하면 더 간단히 같은 작업을 시행할 수 있다.

text = "A press release is the quickest and easiest way to get free
publicity. If well written, a press release can result in multiple published
articles about your firm and its products. And that can mean new prospects
contacting you asking you to sell to them. ... ".lower().split()

print(Counter(text))

출력결과: 
Counter({'and': 3, 'to': 3, can': 2, 'press': 2, 'release': 2, 'you': 2, 'a': 2, 'sell': 1,
'about': 1, 'free': 1, 'firm': 1, 'quickest': 1, 'products.': 1, 'written,': 1, 'them.': 1,
'….': 1, 'articles': 1, 'published' : 1, mean': 1, 'that': 1, 'prospects': 1, 'its': 1,
multiple': 1, 'if' : 1, easiest': 1, 'publicity.': 1, way': 1, 'new": 1, 'result': 1,
'the': 1, 'your': 1, well': 1, 'is': 1, 'asking": 1, 'in': 1, 'contacting : 1, 'get': 1})

Counter은 단순히 시퀀스 자료형의 개수를 세는 것뿐만아니라, 딕셔너리 형태나 키워드 형태의 매개변수를 사용하여 Counter를 생성할 수 있다.

다음은 딕셔너리 형태로 Counter 객체를 생성하는 방법이다. 아래 코드를 보면, {'red': 4, 'blue': 2}라는 초깃값을 사용하여 Counter를 생성한 것을 확인할 수 있다. 또한, elements() 함수를 사용하여, 각 요소의 개수만큼 리스트형의 결과를 출력하는 것을 확인할 수 있다.

from collections import Counter

c = Counter({'red': 4, 'blue': 2})
print(c)
print(list(c.elements()))

출력 결과:
Counter({'red': 4, 'blue': 2})
['red', 'red', 'red', 'red', 'blue', 'blue']

Counter 관련 메소드, 연산자

메소드, 연산자설명
.update()Counter의 값을 갱신한다. 문자열 형태의 입력도 가능하다.
.most_common(n)입력값 요소들 중 빈도수가 높은 순으로 상위 n개를 리스트 안의 튜플 형태로 반환한다.
n이 없을 경우 요소전체를 반환한다.
.subtract()counter에서 요소를 뺀다. counter과 counter를 빼는 것도 가능하다. 만일 해당 요소가 없다면 음수를 나타낸다.
+, - 연산자counter의 덧셈과 뺄셈을 한다. 이때 뺄셈의 경우 음수 값은 출력하지 않는다.
| 연산자두 객체에서 하나가 포함되어 있다면, 그리고 더 큰 값이 있다면 그 값을 합집합을 적용한다.
& 연산자두 객체에서의 교집합을 담당한다.
from collections import Counter
# update.문자열
## 빈 counter 생성
a=Counter()
a.update("abcdefg")
print(a)
# update.문자열
a.update({'f':3,'e':2})
print(a)

print('------------------------------')
# most_common(n)
print(a.most_common())
print(a.most_common(3))

print('------------------------------')
# subtract()
c3 = Counter('hello python')
c4 = Counter('i love python')
c3.subtract(c4)
print(c3)

c = Counter(a=4, b=2, c=0, d=-2)
d = Counter(a=1, b=2, c=3, d=4)
c.subtract(d)
print(c)

print('------------------------------')
# 덧셈 연산자, 뺄셈 연산자
a = Counter(['a', 'b', 'c', 'b', 'd', 'a'])
b = Counter('aaeroplane')
print(a)
print(b)
print(a+b)

a = Counter('aabbccdd')
b = Counter('abbbce')
print(a-b)

print('------------------------------')
# 두 객체의 교집합 , 합집합
a = Counter('aabbccdd')
b = Counter('aabbbce')
print(a & b)
print(a | b)

출력 결과:
Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1, 'g': 1})
Counter({'f': 4, 'e': 3, 'a': 1, 'b': 1, 'c': 1, 'd': 1, 'g': 1})
------------------------------
[('f', 4), ('e', 3), ('a', 1), ('b', 1), ('c', 1), ('d', 1), ('g', 1)]
[('f', 4), ('e', 3), ('a', 1)]
------------------------------
Counter({'h': 1, 'l': 1, 'e': 0, 'o': 0, 'p': 0, 'y': 0, 't': 0, 'n': 0, ' ': -1, 'i': -1, 'v': -1})
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
------------------------------
Counter({'a': 2, 'b': 2, 'c': 1, 'd': 1})
Counter({'a': 3, 'e': 2, 'r': 1, 'o': 1, 'p': 1, 'l': 1, 'n': 1})
Counter({'a': 5, 'b': 2, 'e': 2, 'c': 1, 'd': 1, 'r': 1, 'o': 1, 'p': 1, 'l': 1, 'n': 1})
Counter({'d': 2, 'a': 1, 'c': 1})
------------------------------
Counter({'a': 2, 'b': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 2, 'd': 2, 'e': 1})

namedtuple 모듈

C언어의 structure와 매우 유사하다. namedtuple 모듈은 튜플의 형태로 데이터 구조체를 저장하는 방법으로 특정한 데이터에 각각 규정된 정보가 담겨져있다.
예를 들어 학생이란 데이터에는 이름, 학번, 나이 등의 여러 규정된 정보가 담겨져 있다. 이러한 정보를 하나의 리스트로 만들어 이차원 리스트 형태로 구성해도 될 것이다. 그러나 이 경우, 나중에 이 리스트를 다른 사람이 사용한다면 누구의 어떠한 정보인지 모르는 경우가 발생하여 사용이 어려울 수 있다. 그래서 이러한 정보를 하나의 튜플 형태로 구성해 손쉽게 사용할 수 있는 자료구조가 namedtuple이다.

# 일반 튜플의 경우 각 자리의 값이 무엇을 나타내는지 알기 힘들다.
a = ('John', 28, '남')
b = ('Sally', 24, '여')
for n in [a, b]:
	print('%s은(는) %d 세의 %s성 입니다.' %n)

출력 결과:
John은() 28 세의 남성 입니다.
Sally은() 24 세의 여성 입니다.
--------------------------------------------------

import collections

# namedtuple() 의 경우
Person = collections.namedtuple("Person", 'name age gender')
P1 = Person(name=‘Jhon', age=28, gender='남')
P2 = Person(name='Sally', age=28, gender='여')
for n in [P1, P2]:
	print('%s는(은) %d세의 %s성 입니다.' %n)
   
print(P1.name, P1.age, P1.gender)
print(P2.name, P2.age, P2.gender)

출력 결과:
Jhon는() 28세의 남성 입니다.
Sally는() 28세의 여성 입니다.
Jhon 28 남
Sally 28

namedtuple 관련 메소드

메소드설명
._make()기존에 생성된 namedtuple()에 새로운 객체를 생성하는 메소드이다.
._replace()기존의 객체의 값을 변경할 때 사용하는 메소드이다.
._filed()생성된 namedtuple()의 필드명(filed_names)를 tuple()형태로 반환해준다.
getattr()field_names로 namedtuple()의 인스턴스(객체)의 값을 추출해준다.
double-star-operator(**)double-star-operator(**)는 딕셔너리(dict)를 namedtuple()로 변환해준다.
import collections

# namedtuple 생성
Person = collections.namedtuple("Person", 'name age gender')
P1 = Person(name='Jhon', age=28, gender='남')
P2 = Person(name='Sally', age=28, gender='여')

# _make()를 이용하여 새로운 객체 생성
# 매개변수로 시퀀스 자료형(리스트, 튜플 등)이 들어간다.
P3=Person._make(['Tom', 24, '남'])

# 출력
for n in [P1, P2, P3]:
	print('%s는(은) %d세의 %s성 입니다.' %n)

print("-----------------------------")
# _replace()를 이용하여 인스턴스 값 변경
P1 = P1._replace(name='Neo')
P2 = P2._replace(age=27)
P3 = P3._replace(age=26)

# 출력
for n in [P1, P2, P3]:
	print('%s는(은) %d세의 %s성 입니다.' %n)

print("-----------------------------")
# _fields를 이용하여 필드명 출력
print(P1._fields)

print("-----------------------------")
# getattr를 통해 인스턴스(객체)의 값 추출
print(getattr(P1,'name'))
print(getattr(P1,'gender'))

print("-----------------------------")
# double-star-operator(**)
dic = {'name' : 'jax', 'age' : 24, 'gender' : '여'}
P4 = Person(**dic)

for n in [P1, P2, P3 ,P4]:
	print(n)

출력 결과:
Jhon는() 28세의 남성 입니다.
Sally는() 28세의 여성 입니다.
Tom는() 24세의 남성 입니다.
-----------------------------
Neo는() 28세의 남성 입니다.
Sally는() 27세의 여성 입니다.
Tom는() 26세의 남성 입니다.
-----------------------------
('name', 'age', 'gender')
-----------------------------
Neo
남
-----------------------------
Person(name='Neo', age=28, gender='남')
Person(name='Sally', age=27, gender='여')
Person(name='Tom', age=26, gender='남')
Person(name='jax', age=24, gender='여')

좋은 웹페이지 즐겨찾기