collections
— Container datatypes¶
소스 코드: Lib/collections/__init__.py
이 모듈은 파이썬의 범용 내장 컨테이너 dict
, list
, set
및 tuple
에 대한 대안을 제공하는 특수 컨테이너 데이터형을 구현합니다.
이름 붙은 필드를 갖는 튜플 서브 클래스를 만들기 위한 팩토리 함수 |
|
양쪽 끝에서 빠르게 추가와 삭제를 할 수 있는 리스트류 컨테이너 |
|
여러 매핑의 단일 뷰를 만드는 딕셔너리류 클래스 |
|
dict subclass for counting hashable objects |
|
항목이 추가된 순서를 기억하는 딕셔너리 서브 클래스 |
|
누락된 값을 제공하기 위해 팩토리 함수를 호출하는 딕셔너리 서브 클래스 |
|
더 쉬운 딕셔너리 서브 클래싱을 위해 딕셔너리 객체를 감싸는 래퍼 |
|
더 쉬운 리스트 서브 클래싱을 위해 리스트 객체를 감싸는 래퍼 |
|
더 쉬운 문자열 서브 클래싱을 위해 문자열 객체를 감싸는 래퍼 |
ChainMap
객체¶
Added in version 3.3.
ChainMap
클래스는 여러 매핑을 빠르게 연결하여 단일 단위로 취급 할 수 있도록 합니다. 종종 새로운 딕셔너리를 만들고 여러 update()
호출을 실행하는 것보다 훨씬 빠릅니다.
이 클래스는 중첩된 스코프를 시뮬레이션하는 데 사용할 수 있으며 템플릿에 유용합니다.
- class collections.ChainMap(*maps)¶
ChainMap
은 여러 딕셔너리나 다른 매핑을 함께 묶어 갱신 가능한 단일 뷰를 만듭니다. maps가 지정되지 않으면, 새 체인에 항상 하나 이상의 매핑이 있도록, 빈 딕셔너리 하나가 제공됩니다.하부 매핑은 리스트에 저장됩니다. 이 리스트는 공개이며 maps 어트리뷰트를 사용하여 액세스하거나 갱신할 수 있습니다. 다른 상태는 없습니다.
조회는 키를 찾을 때까지 하부 매핑을 검색합니다. 반면에, 쓰기, 갱신 및 삭제는 첫 번째 매핑에만 작동합니다.
ChainMap
은 하부 매핑을 참조로 통합합니다. 따라서 하부 매핑 중 하나가 갱신되면 해당 변경 사항이ChainMap
에 반영됩니다.일반적인 딕셔너리 메서드가 모두 지원됩니다. 또한, maps 어트리뷰트, 새 서브 컨텍스트를 만드는 메서드 및 첫 번째 매핑을 제외한 모든 것에 액세스하는 프로퍼티가 있습니다:
- maps¶
사용자 갱신 가능한 매핑 리스트. 리스트는 먼저 검색되는 것에서 나중에 검색되는 순서를 따릅니다. 저장된 유일한 상태이며 검색할 매핑을 변경하도록 수정할 수 있습니다. 리스트는 항상 하나 이상의 매핑이 포함되어야 합니다.
- new_child(m=None, **kwargs)¶
Returns a new
ChainMap
containing a new map followed by all of the maps in the current instance. Ifm
is specified, it becomes the new map at the front of the list of mappings; if not specified, an empty dict is used, so that a call tod.new_child()
is equivalent to:ChainMap({}, *d.maps)
. If any keyword arguments are specified, they update passed map or new empty dict. This method is used for creating subcontexts that can be updated without altering values in any of the parent mappings.버전 3.4에서 변경: 선택적
m
매개 변수가 추가되었습니다.버전 3.10에서 변경: Keyword arguments support was added.
- parents¶
첫 번째 맵을 제외하고 현재 인스턴스의 모든 맵을 포함하는 새
ChainMap
을 반환하는 프로퍼티. 검색에서 첫 번째 맵을 건너뛰려고 할 때 유용합니다. 사용 사례는 중첩된 스코프에서 사용되는nonlocal
키워드와 유사합니다. 사용 사례는 내장super()
함수와도 유사합니다.d.parents
에 대한 참조는ChainMap(*d.maps[1:])
과 동등합니다.
Note, the iteration order of a
ChainMap
is determined by scanning the mappings last to first:>>> baseline = {'music': 'bach', 'art': 'rembrandt'} >>> adjustments = {'art': 'van gogh', 'opera': 'carmen'} >>> list(ChainMap(adjustments, baseline)) ['music', 'art', 'opera']
이것은 마지막 매핑에서 시작하는 일련의
dict.update()
호출과 같은 순서를 제공합니다:>>> combined = baseline.copy() >>> combined.update(adjustments) >>> list(combined) ['music', 'art', 'opera']
버전 3.9에서 변경: PEP 584에 지정된,
|
와|=
연산자에 대한 지원이 추가되었습니다.
더 보기
Enthought CodeTools 패키지의 MultiContext 클래스에는 체인의 모든 매핑으로의 쓰기를 지원하는 옵션이 있습니다.
템플릿을 위한 Django의 Context 클래스는 읽기 전용 매핑 체인입니다. 또한
new_child()
메서드와parents
프로퍼티와 유사하게 컨텍스트를 푸시(push)하고 팝(pop) 하는 기능이 있습니다.The Nested Contexts recipe has options to control whether writes and other mutations apply only to the first mapping or to any mapping in the chain.
ChainMap
예제와 조리법¶
이 절에서는 체인 맵으로 작업하는 다양한 접근 방식을 보여줍니다.
파이썬의 내부 조회 체인을 시뮬레이션하는 예:
import builtins
pylookup = ChainMap(locals(), globals(), vars(builtins))
사용자 지정 명령 줄 인자가 환경 변수보다 우선하고, 환경 변수는 기본값보다 우선하도록 하는 예:
import os, argparse
defaults = {'color': 'red', 'user': 'guest'}
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args()
command_line_args = {k: v for k, v in vars(namespace).items() if v is not None}
combined = ChainMap(command_line_args, os.environ, defaults)
print(combined['color'])
print(combined['user'])
중첩된 컨텍스트를 시뮬레이션하기 위해 ChainMap
클래스를 사용하는 예제 패턴:
c = ChainMap() # Create root context
d = c.new_child() # Create nested child context
e = c.new_child() # Child of c, independent from d
e.maps[0] # Current context dictionary -- like Python's locals()
e.maps[-1] # Root context -- like Python's globals()
e.parents # Enclosing context chain -- like Python's nonlocals
d['x'] = 1 # Set value in current context
d['x'] # Get first key in the chain of contexts
del d['x'] # Delete from current context
list(d) # All nested values
k in d # Check all nested values
len(d) # Number of nested values
d.items() # All nested items
dict(d) # Flatten into a regular dictionary
ChainMap
클래스는 체인의 첫 번째 매핑만 갱신(쓰기와 삭제)하지만, 조회는 전체 체인을 검색합니다. 그러나, 깊은 쓰기와 삭제가 필요하면, 체인의 더 깊은 곳에서 발견된 키를 갱신하는 서브 클래스를 쉽게 만들 수 있습니다:
class DeepChainMap(ChainMap):
'Variant of ChainMap that allows direct updates to inner scopes'
def __setitem__(self, key, value):
for mapping in self.maps:
if key in mapping:
mapping[key] = value
return
self.maps[0][key] = value
def __delitem__(self, key):
for mapping in self.maps:
if key in mapping:
del mapping[key]
return
raise KeyError(key)
>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})
>>> d['lion'] = 'orange' # update an existing key two levels down
>>> d['snake'] = 'red' # new keys get added to the topmost dict
>>> del d['elephant'] # remove an existing key one level down
>>> d # display result
DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})
Counter
객체¶
편리하고 빠르게 개수를 세도록 지원하는 계수기 도구가 제공됩니다. 예를 들면:
>>> # Tally occurrences of words in a list
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
... cnt[word] += 1
...
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})
>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
- class collections.Counter([iterable-or-mapping])¶
A
Counter
is adict
subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts. TheCounter
class is similar to bags or multisets in other languages.요소는 이터러블로부터 계산되거나 다른 매핑(또는 계수기)에서 초기화됩니다:
>>> c = Counter() # a new, empty counter >>> c = Counter('gallahad') # a new counter from an iterable >>> c = Counter({'red': 4, 'blue': 2}) # a new counter from a mapping >>> c = Counter(cats=4, dogs=8) # a new counter from keyword args
계수기 객체는 누락된 항목에 대해
KeyError
를 발생시키는 대신 0을 반환한다는 점을 제외하고 딕셔너리 인터페이스를 갖습니다:>>> c = Counter(['eggs', 'ham']) >>> c['bacon'] # count of a missing element is zero 0
개수를 0으로 설정해도 계수기에서 요소가 제거되지 않습니다. 완전히 제거하려면
del
을 사용하십시오:>>> c['sausage'] = 0 # counter entry with a zero count >>> del c['sausage'] # del actually removes the entry
Added in version 3.1.
버전 3.7에서 변경: As a
dict
subclass,Counter
inherited the capability to remember insertion order. Math operations on Counter objects also preserve order. Results are ordered according to when an element is first encountered in the left operand and then by the order encountered in the right operand.Counter objects support additional methods beyond those available for all dictionaries:
- elements()¶
개수만큼 반복되는 요소에 대한 이터레이터를 반환합니다. 요소는 처음 발견되는 순서대로 반환됩니다. 요소의 개수가 1보다 작으면
elements()
는 이를 무시합니다.>>> c = Counter(a=4, b=2, c=0, d=-2) >>> sorted(c.elements()) ['a', 'a', 'a', 'a', 'b', 'b']
- most_common([n])¶
n 개의 가장 흔한 요소와 그 개수를 가장 흔한 것부터 가장 적은 것 순으로 나열한 리스트를 반환합니다. n이 생략되거나
None
이면,most_common()
은 계수기의 모든 요소를 반환합니다. 개수가 같은 요소는 처음 발견된 순서를 유지합니다:>>> Counter('abracadabra').most_common(3) [('a', 5), ('b', 2), ('r', 2)]
- subtract([iterable-or-mapping])¶
이터러블이나 다른 매핑 (또는 계수기)으로부터 온 요소들을 뺍니다.
dict.update()
와 비슷하지만 교체하는 대신 개수를 뺍니다. 입력과 출력 모두 0이나 음수일 수 있습니다.>>> c = Counter(a=4, b=2, c=0, d=-2) >>> d = Counter(a=1, b=2, c=3, d=4) >>> c.subtract(d) >>> c Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
Added in version 3.2.
- total()¶
Compute the sum of the counts.
>>> c = Counter(a=10, b=5, c=0) >>> c.total() 15
Added in version 3.10.
일반적인 딕셔너리 메서드를
Counter
객체에 사용할 수 있습니다만, 두 메서드는 계수기에서 다르게 동작합니다.- update([iterable-or-mapping])¶
요소는 이터러블에서 세거나 다른 매핑(또는 계수기)에서 더해집니다.
dict.update()
와 비슷하지만, 교체하는 대신 더합니다. 또한, 이터러블은(key, value)
쌍의 시퀀스가 아닌, 요소의 시퀀스일 것으로 기대합니다.
Counters support rich comparison operators for equality, subset, and
superset relationships: ==
, !=
, <
, <=
, >
, >=
.
All of those tests treat missing elements as having zero counts so that
Counter(a=1) == Counter(a=1, b=0)
returns true.
버전 3.10에서 변경: Rich comparison operations were added.
버전 3.10에서 변경: In equality tests, missing elements are treated as having zero counts.
Formerly, Counter(a=3)
and Counter(a=3, b=0)
were considered
distinct.
Counter
객체로 작업하는 일반적인 패턴:
c.total() # total of all counts
c.clear() # reset all counts
list(c) # list unique elements
set(c) # convert to a set
dict(c) # convert to a regular dictionary
c.items() # access the (elem, cnt) pairs
Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs
c.most_common()[:-n-1:-1] # n least common elements
+c # remove zero and negative counts
Several mathematical operations are provided for combining Counter
objects to produce multisets (counters that have counts greater than zero).
Addition and subtraction combine counters by adding or subtracting the counts
of corresponding elements. Intersection and union return the minimum and
maximum of corresponding counts. Equality and inclusion compare
corresponding counts. Each operation can accept inputs with signed
counts, but the output will exclude results with counts of zero or less.
>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d # add two counters together: c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d # subtract (keeping only positive counts)
Counter({'a': 2})
>>> c & d # intersection: min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d # union: max(c[x], d[x])
Counter({'a': 3, 'b': 2})
>>> c == d # equality: c[x] == d[x]
False
>>> c <= d # inclusion: c[x] <= d[x]
False
단항 덧셈과 뺄셈은 빈 계수기를 더하거나 빈 계수기를 빼는 것의 줄임 표현입니다.
>>> c = Counter(a=2, b=-4)
>>> +c
Counter({'a': 2})
>>> -c
Counter({'b': 4})
Added in version 3.3: 단항 플러스, 단항 마이너스 및 제자리 멀티 셋 연산에 대한 지원이 추가되었습니다.
참고
계수기는 주로 양의 정수로 작동하여 횟수를 나타내도록 설계되었습니다; 그러나, 다른 형이나 음수 값이 필요한 사용 사례를 불필요하게 배제하지 않도록 주의를 기울였습니다. 이러한 사용 사례에 도움이 되도록, 이 절은 최소 범위와 형 제약 사항을 설명합니다.
Counter
클래스 자체는 키와 값에 제한이 없는 딕셔너리 서브 클래스입니다. 값은 개수를 나타내는 숫자로 의도되었지만, 값 필드에 어떤 것이든 저장할 수 있습니다.most_common()
메서드는 값에 대해 순서만을 요구합니다.c[key] += 1
과 같은 제자리 연산의 경우, 값 형은 덧셈과 뺄셈만 지원하면 됩니다. 따라서 분수(fractions), 부동 소수점(floats) 및 십진수(decimals)가 작동하고 음수 값이 지원됩니다.update()
와subtract()
에 대해서도 마찬가지인데, 입력과 출력 모두 음수와 0을 허용합니다.멀티 셋(multiset) 메서드는 양의 값에 대한 사용 사례를 위해서만 설계되었습니다. 입력은 음수이거나 0일 수 있지만, 양수 값을 갖는 출력만 만들어집니다. 형 제한은 없지만, 값 형은 더하기, 빼기 및 비교를 지원해야 합니다.
elements()
메서드는 정수 개수를 요구합니다. 0과 음수 개수는 무시합니다.
더 보기
스몰토크(Smalltalk)의 Bag 클래스.
Multisets에 대한 위키피디아 항목.
예제가 포함된 C++ multisets 자습서.
멀티 셋에 대한 수학 연산과 그 사용 사례에 대해서는, Knuth, Donald. The Art of Computer Programming Volume II, Section 4.6.3, Exercise 19를 참조하십시오.
주어진 요소 집합에 대해 주어진 크기의 모든 서로 다른 멀티 셋을 열거하려면,
itertools.combinations_with_replacement()
를 참조하십시오:map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC
deque
객체¶
- class collections.deque([iterable[, maxlen]])¶
iterable의 데이터로 왼쪽에서 오른쪽으로 (
append()
를 사용해서) 초기화된 새 데크(deque) 객체를 반환합니다. iterable을 지정하지 않으면, 새 데크는 비어 있습니다.Deques are a generalization of stacks and queues (the name is pronounced “deck” and is short for “double-ended queue”). Deques support thread-safe, memory efficient appends and pops from either side of the deque with approximately the same O(1) performance in either direction.
Though
list
objects support similar operations, they are optimized for fast fixed-length operations and incur O(n) memory movement costs forpop(0)
andinsert(0, v)
operations which change both the size and position of the underlying data representation.maxlen이 지정되지 않거나
None
이면, 데크는 임의의 길이로 커질 수 있습니다. 그렇지 않으면, 데크는 지정된 최대 길이로 제한됩니다. 일단 제한된 길이의 데크가 가득 차면, 새 항목이 추가될 때, 해당하는 수의 항목이 반대쪽 끝에서 삭제됩니다. 제한된 길이의 데크는 유닉스의tail
필터와 유사한 기능을 제공합니다. 또한 가장 최근 활동만 관심이 있는 트랜잭션과 기타 데이터 풀을 추적하는 데 유용합니다.deque 객체는 다음 메서드를 지원합니다:
- append(x)¶
데크의 오른쪽에 x를 추가합니다.
- appendleft(x)¶
데크의 왼쪽에 x를 추가합니다.
- clear()¶
데크에서 모든 요소를 제거하고 길이가 0인 상태로 만듭니다.
- copy()¶
데크의 얕은 복사본을 만듭니다.
Added in version 3.5.
- count(x)¶
x 와 같은 데크 요소의 수를 셉니다.
Added in version 3.2.
- extend(iterable)¶
iterable 인자에서 온 요소를 추가하여 데크의 오른쪽을 확장합니다.
- extendleft(iterable)¶
iterable에서 온 요소를 추가하여 데크의 왼쪽을 확장합니다. 일련의 왼쪽 추가는 iterable 인자에 있는 요소의 순서를 뒤집는 결과를 줍니다.
- index(x[, start[, stop]])¶
데크에 있는 x의 위치를 반환합니다 (인덱스 start 또는 그 이후, 그리고 인덱스 stop 이전). 첫 번째 일치를 반환하거나 찾을 수 없으면
ValueError
를 발생시킵니다.Added in version 3.5.
- insert(i, x)¶
x를 데크의 i 위치에 삽입합니다.
삽입으로 인해 제한된 길이의 데크가 maxlen 이상으로 커지면,
IndexError
가 발생합니다.Added in version 3.5.
- pop()¶
데크의 오른쪽에서 요소를 제거하고 반환합니다. 요소가 없으면,
IndexError
를 발생시킵니다.
- popleft()¶
데크의 왼쪽에서 요소를 제거하고 반환합니다. 요소가 없으면,
IndexError
를 발생시킵니다.
- remove(value)¶
value의 첫 번째 항목을 제거합니다. 찾을 수 없으면,
ValueError
를 발생시킵니다.
- reverse()¶
데크의 요소들을 제자리에서 순서를 뒤집고
None
을 반환합니다.Added in version 3.2.
- rotate(n=1)¶
데크를 n 단계 오른쪽으로 회전합니다. n이 음수이면, 왼쪽으로 회전합니다.
데크가 비어 있지 않으면, 오른쪽으로 한 단계 회전하는 것은
d.appendleft(d.pop())
과 동등하고, 왼쪽으로 한 단계 회전하는 것은d.append(d.popleft())
와 동등합니다.
데크 객체는 하나의 읽기 전용 어트리뷰트도 제공합니다:
- maxlen¶
데크의 최대 크기 또는 제한이 없으면
None
.Added in version 3.1.
In addition to the above, deques support iteration, pickling, len(d)
,
reversed(d)
, copy.copy(d)
, copy.deepcopy(d)
, membership testing with
the in
operator, and subscript references such as d[0]
to access
the first element. Indexed access is O(1) at both ends but slows to O(n) in
the middle. For fast random access, use lists instead.
버전 3.5부터, 데크는 __add__()
, __mul__()
및 __imul__()
을 지원합니다.
예:
>>> from collections import deque
>>> d = deque('ghi') # make a new deque with three items
>>> for elem in d: # iterate over the deque's elements
... print(elem.upper())
G
H
I
>>> d.append('j') # add a new entry to the right side
>>> d.appendleft('f') # add a new entry to the left side
>>> d # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])
>>> d.pop() # return and remove the rightmost item
'j'
>>> d.popleft() # return and remove the leftmost item
'f'
>>> list(d) # list the contents of the deque
['g', 'h', 'i']
>>> d[0] # peek at leftmost item
'g'
>>> d[-1] # peek at rightmost item
'i'
>>> list(reversed(d)) # list the contents of a deque in reverse
['i', 'h', 'g']
>>> 'h' in d # search the deque
True
>>> d.extend('jkl') # add multiple elements at once
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1) # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1) # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> deque(reversed(d)) # make a new deque in reverse order
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear() # empty the deque
>>> d.pop() # cannot pop from an empty deque
Traceback (most recent call last):
File "<pyshell#6>", line 1, in -toplevel-
d.pop()
IndexError: pop from an empty deque
>>> d.extendleft('abc') # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])
deque
조리법¶
이 절은 데크로 작업하는 다양한 접근 방식을 보여줍니다.
제한된 길이의 데크는 유닉스의 tail
필터와 유사한 기능을 제공합니다:
def tail(filename, n=10):
'Return the last n lines of a file'
with open(filename) as f:
return deque(f, n)
데크를 사용하는 또 다른 접근법은 오른쪽에 추가하고 왼쪽에서 팝 하여 최근에 추가된 요소의 시퀀스를 유지하는 것입니다:
def moving_average(iterable, n=3):
# moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0
# https://en.wikipedia.org/wiki/Moving_average
it = iter(iterable)
d = deque(itertools.islice(it, n-1))
d.appendleft(0)
s = sum(d)
for elem in it:
s += elem - d.popleft()
d.append(elem)
yield s / n
라운드 로빈 스케줄러(round-robin scheduler)는 deque
에 저장된 입력 이터레이터로 구현할 수 있습니다. 위치 0에 있는 활성 이터레이터에서 값이 산출됩니다. 그 이터레이터가 소진되면, popleft()
로 제거할 수 있습니다; 그렇지 않으면, rotate()
메서드로 끝으로 보내 순환할 수 있습니다:
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
iterators = deque(map(iter, iterables))
while iterators:
try:
while True:
yield next(iterators[0])
iterators.rotate(-1)
except StopIteration:
# Remove an exhausted iterator.
iterators.popleft()
rotate()
메서드는 deque
슬라이싱과 삭제를 구현하는 방법을 제공합니다. 예를 들어, del d[n]
의 순수 파이썬 구현은 팝 될 요소의 위치를 잡기 위해 rotate()
메서드에 의존합니다:
def delete_nth(d, n):
d.rotate(-n)
d.popleft()
d.rotate(n)
deque
슬라이싱을 구현하려면, 대상 요소를 데크의 왼쪽으로 가져오기 위해 rotate()
를 적용하는 유사한 접근법을 사용하십시오. popleft()
로 이전 항목을 제거하고, extend()
로 새 항목을 추가한 다음, 회전을 되돌립니다. 이 접근 방식에 약간의 변형을 가하면, dup
, drop
, swap
, over
, pick
, rot
및 roll
과 같은 Forth 스타일 스택 조작을 쉽게 구현할 수 있습니다.
defaultdict
객체¶
- class collections.defaultdict(default_factory=None, /[, ...])¶
Return a new dictionary-like object.
defaultdict
is a subclass of the built-indict
class. It overrides one method and adds one writable instance variable. The remaining functionality is the same as for thedict
class and is not documented here.첫 번째 인자는
default_factory
어트리뷰트의 초깃값을 제공합니다; 기본값은None
입니다. 나머지 모든 인자는 키워드 인자를 포함하여dict
생성자에 전달될 때와 마찬가지로 취급됩니다.defaultdict
객체는 표준dict
연산 외에도 다음 메서드를 지원합니다:- __missing__(key)¶
default_factory
어트리뷰트가None
이면, key를 인자로 사용하는KeyError
예외가 발생합니다.default_factory
가None
이 아니면, 주어진 key에 대한 기본값을 제공하기 위해 인자 없이 호출되며, 반환 값은 key로 딕셔너리에 삽입되고 반환됩니다.default_factory
를 호출할 때 예외가 발생하면 이 예외는 변경되지 않고 전파됩니다.This method is called by the
__getitem__()
method of thedict
class when the requested key is not found; whatever it returns or raises is then returned or raised by__getitem__()
.Note that
__missing__()
is not called for any operations besides__getitem__()
. This means thatget()
will, like normal dictionaries, returnNone
as a default rather than usingdefault_factory
.
defaultdict
객체는 다음 인스턴스 변수를 지원합니다:- default_factory¶
이 어트리뷰트는
__missing__()
메서드에서 사용됩니다; 생성자의 첫 번째 인자가 있으면 그것으로, 없으면None
으로 초기화됩니다.
버전 3.9에서 변경: PEP 584에 지정된, 병합(
|
)과 업데이트(|=
) 연산자가 추가되었습니다.
defaultdict
예¶
list
를 default_factory
로 사용하면, 키-값 쌍의 시퀀스를 리스트의 딕셔너리로 쉽게 그룹화 할 수 있습니다:
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
When each key is encountered for the first time, it is not already in the
mapping; so an entry is automatically created using the default_factory
function which returns an empty list
. The list.append()
operation then attaches the value to the new list. When keys are encountered
again, the look-up proceeds normally (returning the list for that key) and the
list.append()
operation adds another value to the list. This technique is
simpler and faster than an equivalent technique using dict.setdefault()
:
>>> d = {}
>>> for k, v in s:
... d.setdefault(k, []).append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
default_factory
를 int
로 설정하면 defaultdict
를 세는(counting) 데 유용하게 사용할 수 있습니다 (다른 언어의 백(bag)이나 멀티 셋(multiset)처럼):
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> sorted(d.items())
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]
글자가 처음 발견될 때, 매핑에서 누락되었으므로, default_factory
함수는 int()
를 호출하여 기본 계수 0을 제공합니다. 증분 연산은 각 문자의 개수를 쌓아나갑니다.
항상 0을 반환하는 함수 int()
는 상수 함수의 특별한 경우일 뿐입니다. 상수 함수를 만드는 더 빠르고 유연한 방법은 (단지 0이 아니라) 임의의 상숫값을 제공 할 수 있는 람다 함수를 사용하는 것입니다:
>>> def constant_factory(value):
... return lambda: value
...
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'
default_factory
를 set
으로 설정하면, defaultdict
를 집합의 딕셔너리를 만드는 데 유용하게 만듭니다:
>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
... d[k].add(v)
...
>>> sorted(d.items())
[('blue', {2, 4}), ('red', {1, 3})]
이름있는 필드를 가진 튜플을 위한 namedtuple()
팩토리 함수¶
네임드 튜플은 튜플의 각 위치에 의미를 부여하고 더 읽기 쉽고 스스로 설명하는 코드를 만들도록 합니다. 일반 튜플이 사용되는 곳이라면 어디에서나 사용할 수 있으며, 위치 인덱스 대신 이름으로 필드에 액세스하는 기능을 추가합니다.
- collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)¶
typename이라는 이름의 새 튜플 서브 클래스를 반환합니다. 새로운 서브 클래스는 인덱싱되고 이터러블일 뿐만 아니라 어트리뷰트 조회로 액세스 할 수 있는 필드를 갖는 튜플류 객체를 만드는 데 사용됩니다. 서브 클래스의 인스턴스에는 유용한 독스트링(typename과 field_names를 포함합니다)과 튜플 내용을
name=value
형식으로 나열하는 유용한__repr__()
메서드가 있습니다.field_names는
['x', 'y']
와 같은 문자열의 시퀀스입니다. 또는, field_names는 각 필드명이 공백 및/또는 쉼표로 구분된 단일 문자열일 수 있습니다, 예를 들어'x y'
나'x, y'
.밑줄로 시작하는 이름을 제외한 모든 유효한 파이썬 식별자를 필드명에 사용할 수 있습니다. 유효한 식별자는 글자, 숫자 및 밑줄로 구성되지만, 숫자나 밑줄로 시작하지 않으며 class, for, return, global, pass 또는 raise와 같은
keyword
일 수 없습니다.rename이 참이면, 유효하지 않은 필드명은 위치 이름으로 자동 대체됩니다. 예를 들어,
['abc', 'def', 'ghi', 'abc']
는['abc', '_1', 'ghi', '_3']
으로 변환되어 키워드def
와 중복된 필드명abc
를 제거합니다.defaults는
None
이나 기본값의 이터러블 일 수 있습니다. 기본값이 있는 필드는 기본값이 없는 필드 뒤에 와야 하므로, defaults는 가장 오른쪽의 매개 변수에 적용됩니다. 예를 들어, field_names가['x', 'y', 'z']
이고 defaults가(1, 2)
이면x
는 필수 인자이고,y
의 기본값은1
,z
의 기본값은2
입니다.If module is defined, the
__module__
attribute of the named tuple is set to that value.네임드 튜플 인스턴스에는 인스턴스 별 딕셔너리가 없어서, 가볍고 일반 튜플보다 더 많은 메모리가 필요하지 않습니다.
피클링을 지원하려면, 네임드 튜플 클래스를 typename과 일치하는 변수에 대입해야 합니다.
버전 3.1에서 변경: rename에 대한 지원이 추가되었습니다.
버전 3.6에서 변경: verbose와 rename 매개 변수는 키워드 전용 인자가 되었습니다.
버전 3.6에서 변경: module 매개 변수를 추가했습니다.
버전 3.7에서 변경: verbose 매개 변수와
_source
어트리뷰트를 제거했습니다.버전 3.7에서 변경: defaults 매개 변수와
_field_defaults
어트리뷰트가 추가되었습니다.
>>> # Basic example
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22) # instantiate with positional or keyword arguments
>>> p[0] + p[1] # indexable like the plain tuple (11, 22)
33
>>> x, y = p # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y # fields also accessible by name
33
>>> p # readable __repr__ with a name=value style
Point(x=11, y=22)
네임드 튜플은 csv
나 sqlite3
모듈이 반환한 결과 튜플에 필드 이름을 할당하는 데 특히 유용합니다:
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
print(emp.name, emp.title)
import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
print(emp.name, emp.title)
튜플에서 상속된 메서드 외에도 네임드 튜플은 세 가지 추가 메서드와 두 가지 어트리뷰트를 지원합니다. 필드 이름과의 충돌을 방지하기 위해, 메서드와 어트리뷰트 이름은 밑줄로 시작합니다.
- classmethod somenamedtuple._make(iterable)¶
기존 시퀀스나 이터러블로 새 인스턴스를 만드는 클래스 메서드.
>>> t = [11, 22] >>> Point._make(t) Point(x=11, y=22)
- somenamedtuple._asdict()¶
필드 이름을 해당 값으로 매핑하는 새
dict
를 반환합니다:>>> p = Point(x=11, y=22) >>> p._asdict() {'x': 11, 'y': 22}
버전 3.1에서 변경: 일반
dict
대신OrderedDict
를 반환합니다.버전 3.8에서 변경:
OrderedDict
대신 일반dict
를 반환합니다. 파이썬 3.7부터, 일반 딕셔너리의 순서가 유지되도록 보장합니다.OrderedDict
의 추가 기능이 필요할 때, 제안하는 처방은 결과를 원하는 형으로 캐스트 하는 것입니다:OrderedDict(nt._asdict())
.
- somenamedtuple._replace(**kwargs)¶
지정된 필드들을 새로운 값으로 치환하는 네임드 튜플의 새 인스턴스를 반환합니다:
>>> p = Point(x=11, y=22) >>> p._replace(x=33) Point(x=33, y=22) >>> for partnum, record in inventory.items(): ... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
Named tuples are also supported by generic function
copy.replace()
.버전 3.13에서 변경: Raise
TypeError
instead ofValueError
for invalid keyword arguments.
- somenamedtuple._fields¶
필드 이름을 나열하는 문자열의 튜플. 인트로스펙션과 기존 네임드 튜플에서 새로운 네임드 튜플 형을 만드는 데 유용합니다.
>>> p._fields # view the field names ('x', 'y') >>> Color = namedtuple('Color', 'red green blue') >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields) >>> Pixel(11, 22, 128, 255, 0) Pixel(x=11, y=22, red=128, green=255, blue=0)
- somenamedtuple._field_defaults¶
필드 이름을 기본값으로 매핑하는 딕셔너리.
>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0]) >>> Account._field_defaults {'balance': 0} >>> Account('premium') Account(type='premium', balance=0)
이름이 문자열에 저장된 필드를 조회하려면 getattr()
함수를 사용하십시오.:
>>> getattr(p, 'x')
11
딕셔너리를 네임드 튜플로 변환하려면 이중 애스터리스크 연산자를 사용하십시오 (인자 목록 언 패킹에서 설명합니다).:
>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)
네임드 튜플은 일반적인 파이썬 클래스이므로, 서브 클래스를 사용하여 기능을 쉽게 추가하거나 변경할 수 있습니다. 계산된 필드와 고정 너비 인쇄 포맷을 추가하는 방법은 다음과 같습니다:
>>> class Point(namedtuple('Point', ['x', 'y'])):
... __slots__ = ()
... @property
... def hypot(self):
... return (self.x ** 2 + self.y ** 2) ** 0.5
... def __str__(self):
... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
>>> for p in Point(3, 4), Point(14, 5/7):
... print(p)
Point: x= 3.000 y= 4.000 hypot= 5.000
Point: x=14.000 y= 0.714 hypot=14.018
위에 표시된 서브 클래스는 __slots__
를 빈 튜플로 설정합니다. 이렇게 하면 인스턴스 딕셔너리 생성을 방지하여 메모리 요구 사항을 낮게 유지할 수 있습니다.
서브 클래싱은 저장된 새 필드를 추가하는 데는 유용하지 않습니다. 대신, _fields
어트리뷰트로 새로운 네임드 튜플 형을 만드십시오:
>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))
__doc__
필드에 직접 대입하여 독스트링을 사용자 정의할 수 있습니다:
>>> Book = namedtuple('Book', ['id', 'title', 'authors'])
>>> Book.__doc__ += ': Hardcover book in active collection'
>>> Book.id.__doc__ = '13-digit ISBN'
>>> Book.title.__doc__ = 'Title of first printing'
>>> Book.authors.__doc__ = 'List of authors sorted by last name'
버전 3.5에서 변경: 프로퍼티 독스트링이 쓰기 가능하게 되었습니다.
더 보기
네임드 튜플에 형 힌트를 추가하는 방법은
typing.NamedTuple
을 참조하십시오. 이것은class
키워드를 사용하는 우아한 표기법도 제공합니다:class Component(NamedTuple): part_number: int weight: float description: Optional[str] = None
튜플 대신 하부 딕셔너리를 기반으로 하는 가변 이름 공간에 대해서는
types.SimpleNamespace()
를 참조하십시오.dataclasses
모듈은 사용자 정의 클래스에 생성된 특수 메서드를 자동으로 추가하는 데코레이터와 함수를 제공합니다.
OrderedDict
객체¶
순서 있는 딕셔너리는 일반 딕셔너리와 비슷하지만, 순서를 다루는 연산과 관련된 몇 가지 추가 기능이 있습니다. 내장 dict
클래스가 삽입 순서를 기억하는 기능을 얻었으므로 (이 새로운 동작은 파이썬 3.7에서 보장되었습니다), 이제 덜 중요해졌습니다.
몇 가지 dict
와의 차이점은 여전히 남아 있습니다:
일반
dict
는 매핑 연산에 매우 적합하도록 설계되었습니다. 삽입 순서 추적은 부차적입니다.OrderedDict
는 순서를 바꾸는 연산에 적합하도록 설계되었습니다. 공간 효율성, 이터레이션 속도 및 갱신 연산의 성능은 부차적입니다.The
OrderedDict
algorithm can handle frequent reordering operations better thandict
. As shown in the recipes below, this makes it suitable for implementing various kinds of LRU caches.OrderedDict
의 동등 비교 연산은 순서의 일치를 확인합니다.A regular
dict
can emulate the order sensitive equality test withp == q and all(k1 == k2 for k1, k2 in zip(p, q))
.OrderedDict
의popitem()
메서드는 서명이 다릅니다. 어떤 항목을 팝 할지는 지정하는 선택적 인자를 받아들입니다.A regular
dict
can emulate OrderedDict’sod.popitem(last=True)
withd.popitem()
which is guaranteed to pop the rightmost (last) item.A regular
dict
can emulate OrderedDict’sod.popitem(last=False)
with(k := next(iter(d)), d.pop(k))
which will return and remove the leftmost (first) item if it exists.OrderedDict
에는 요소를 효율적으로 끝으로 재배치하는move_to_end()
메서드가 있습니다.A regular
dict
can emulate OrderedDict’sod.move_to_end(k, last=True)
withd[k] = d.pop(k)
which will move the key and its associated value to the rightmost (last) position.A regular
dict
does not have an efficient equivalent for OrderedDict’sod.move_to_end(k, last=False)
which moves the key and its associated value to the leftmost (first) position.파이썬 3.8 이전에는,
dict
에__reversed__()
메서드가 없었습니다.
- class collections.OrderedDict([items])¶
딕셔너리 순서 재배치에 특화된 메서드가 있는
dict
서브 클래스의 인스턴스를 반환합니다.Added in version 3.1.
- popitem(last=True)¶
순서 있는 딕셔너리의
popitem()
메서드는 (키, 값) 쌍을 반환하고 제거합니다. last가 참이면 쌍이 LIFO 순서로 반환되고, 거짓이면 FIFO 순서로 반환됩니다.
- move_to_end(key, last=True)¶
Move an existing key to either end of an ordered dictionary. The item is moved to the right end if last is true (the default) or to the beginning if last is false. Raises
KeyError
if the key does not exist:>>> d = OrderedDict.fromkeys('abcde') >>> d.move_to_end('b') >>> ''.join(d) 'acdeb' >>> d.move_to_end('b', last=False) >>> ''.join(d) 'bacde'
Added in version 3.2.
일반적인 매핑 메서드 외에도 순서 있는 딕셔너리는 reversed()
를 사용하는 역 이터레이션을 지원합니다.
Equality tests between OrderedDict
objects are order-sensitive
and are roughly equivalent to list(od1.items())==list(od2.items())
.
Equality tests between OrderedDict
objects and other
Mapping
objects are order-insensitive like regular
dictionaries. This allows OrderedDict
objects to be substituted
anywhere a regular dictionary is used.
버전 3.5에서 변경: OrderedDict
의 items, keys 및 values 뷰는 이제 reversed()
를 사용하는 역 이터레이션을 지원합니다.
버전 3.6에서 변경: PEP 468을 수락함에 따라, OrderedDict
생성자와 update()
메서드로 전달된 키워드 인자의 순서가 보존됩니다.
버전 3.9에서 변경: PEP 584에 지정된, 병합(|
)과 업데이트(|=
) 연산자가 추가되었습니다.
OrderedDict
예제와 조리법¶
키가 마지막에 삽입된 순서를 기억하는 순서 있는 딕셔너리 변형을 만드는 것은 간단합니다. 새 항목이 기존 항목을 덮어쓰면, 원래 삽입 위치가 변경되고 끝으로 이동합니다:
class LastUpdatedOrderedDict(OrderedDict):
'Store items in the order the keys were last added'
def __setitem__(self, key, value):
super().__setitem__(key, value)
self.move_to_end(key)
An OrderedDict
would also be useful for implementing
variants of functools.lru_cache()
:
from collections import OrderedDict
from time import time
class TimeBoundedLRU:
"LRU Cache that invalidates and refreshes old entries."
def __init__(self, func, maxsize=128, maxage=30):
self.cache = OrderedDict() # { args : (timestamp, result)}
self.func = func
self.maxsize = maxsize
self.maxage = maxage
def __call__(self, *args):
if args in self.cache:
self.cache.move_to_end(args)
timestamp, result = self.cache[args]
if time() - timestamp <= self.maxage:
return result
result = self.func(*args)
self.cache[args] = time(), result
if len(self.cache) > self.maxsize:
self.cache.popitem(last=False)
return result
class MultiHitLRUCache:
""" LRU cache that defers caching a result until
it has been requested multiple times.
To avoid flushing the LRU cache with one-time requests,
we don't cache until a request has been made more than once.
"""
def __init__(self, func, maxsize=128, maxrequests=4096, cache_after=1):
self.requests = OrderedDict() # { uncached_key : request_count }
self.cache = OrderedDict() # { cached_key : function_result }
self.func = func
self.maxrequests = maxrequests # max number of uncached requests
self.maxsize = maxsize # max number of stored return values
self.cache_after = cache_after
def __call__(self, *args):
if args in self.cache:
self.cache.move_to_end(args)
return self.cache[args]
result = self.func(*args)
self.requests[args] = self.requests.get(args, 0) + 1
if self.requests[args] <= self.cache_after:
self.requests.move_to_end(args)
if len(self.requests) > self.maxrequests:
self.requests.popitem(last=False)
else:
self.requests.pop(args, None)
self.cache[args] = result
if len(self.cache) > self.maxsize:
self.cache.popitem(last=False)
return result
UserDict
객체¶
UserDict
클래스는 딕셔너리 객체를 감싸는 래퍼 역할을 합니다. 이 클래스의 필요성은 dict
에서 직접 서브 클래싱 할 수 있는 능력에 의해 부분적으로 대체되었습니다; 그러나 하부 딕셔너리를 어트리뷰트로 액세스 할 수 있어서, 이 클래스를 사용하면 작업하기가 더 쉬울 수 있습니다.
- class collections.UserDict([initialdata])¶
Class that simulates a dictionary. The instance’s contents are kept in a regular dictionary, which is accessible via the
data
attribute ofUserDict
instances. If initialdata is provided,data
is initialized with its contents; note that a reference to initialdata will not be kept, allowing it to be used for other purposes.UserDict
인스턴스는 매핑의 메서드와 연산을 지원할 뿐만 아니라, 다음과 같은 어트리뷰트를 제공합니다:
UserList
객체¶
이 클래스는 리스트 객체를 둘러싸는 래퍼 역할을 합니다. 여러분 자신의 리스트류 클래스가 상속하고 기존 메서드를 재정의하거나 새로운 메서드를 추가할 수 있는 유용한 베이스 클래스입니다. 이런 식으로 리스트에 새로운 동작을 추가 할 수 있습니다.
이 클래스의 필요성은 list
에서 직접 서브 클래싱할 수 있는 능력에 의해 부분적으로 대체되었습니다; 그러나 하부 리스트에 어트리뷰트로 액세스할 수 있어서, 이 클래스를 사용하면 작업하기가 더 쉬울 수 있습니다.
- class collections.UserList([list])¶
리스트를 시뮬레이트 하는 클래스. 인스턴스의 내용은 일반 리스트로 유지되며
UserList
인스턴스의data
어트리뷰트를 통해 액세스 할 수 있습니다. 인스턴스의 내용은 초기에 list의 사본으로 설정되며, 기본값은 빈 목록[]
입니다. list는 모든 이터러블일 수 있습니다, 예를 들어 실제 파이썬 리스트나UserList
객체.UserList
인스턴스는 가변 시퀀스의 메서드와 연산을 지원할 뿐만 아니라 다음 어트리뷰트를 제공합니다:
서브 클래싱 요구 사항: UserList
의 서브 클래스는 인자가 없거나 하나의 인자로 호출 할 수 있는 생성자를 제공해야 합니다. 새 시퀀스를 반환하는 리스트 연산은 실제 구현 클래스의 인스턴스를 만들려고 시도합니다. 이를 위해, 데이터 소스로 사용되는 시퀀스 객체인 단일 매개 변수로 생성자를 호출할 수 있다고 가정합니다.
파생 클래스가 이 요구 사항을 준수하고 싶지 않다면, 이 클래스에서 지원하는 모든 특수 메서드를 재정의해야 합니다; 이때 제공해야 하는 메서드에 대한 정보는 소스를 참조하십시오.
UserString
객체¶
UserString
클래스는 문자열 객체를 둘러싸는 래퍼 역할을 합니다. 이 클래스의 필요성은 str
에서 직접 서브 클래싱할 수 있는 능력에 의해 부분적으로 대체되었습니다; 그러나 하부 문자열을 어트리뷰트로 액세스할 수 있어서, 이 클래스를 사용하면 작업하기가 더 쉬울 수 있습니다.
- class collections.UserString(seq)¶
문자열 객체를 시뮬레이트 하는 클래스. 인스턴스의 내용은 일반 문자열 객체로 유지되며,
UserString
인스턴스의data
어트리뷰트를 통해 액세스 할 수 있습니다. 인스턴스의 내용은 처음에 seq의 사본으로 설정됩니다. seq 인자는 내장str()
함수를 사용하여 문자열로 변환 할 수 있는 모든 객체가 될 수 있습니다.UserString
인스턴스는 문자열의 메서드와 연산을 지원할 뿐만 아니라 다음과 같은 어트리뷰트를 제공합니다:- data¶
UserString
클래스의 내용을 저장하는 데 사용되는 실제str
객체.
버전 3.5에서 변경: 새로운 메서드
__getnewargs__
,__rmod__
,casefold
,format_map
,isprintable
및maketrans
.