python-collections — 컨테이너 데이터 유형(순서가 지정된 사전)
소스 코드: Lib/collections/ init.py
이 모듈은 대상별 컨테이너를 구현하여 Python 의 표준 내장 컨테이너 dict , list , set 및 tuple 에 대한 대안을 제공합니다.
이름 | 효과 |
---|---|
명명된 튜플() | 명명된 튜플 하위 클래스를 만들기 위한 팩토리 함수 |
그러므로 | 리스트(list)와 유사한 컨테이너로 양쪽 끝에 빠른 추가(append)와 팝업(pop)을 실현 |
체인맵 | 여러 매핑을 보기로 수집하는 사전(dict)과 유사한 컨테이너 클래스 |
카운터 | 해시 가능한 객체에 대한 계산 기능을 제공하는 Dictionary의 하위 클래스 |
OrderedDict | 추가된 순서를 유지하는 Dictionary의 하위 클래스 |
defaultdict | 사전 쿼리에 대한 기본값을 제공하는 팩토리 함수를 제공하는 사전의 하위 클래스 |
UserDict | 사전 객체를 캡슐화하여 사전 서브클래싱을 단순화합니다. |
사용자 목록 | 목록 객체를 캡슐화하여 목록 서브클래싱을 단순화합니다. |
사용자 문자열 | 문자열 개체를 캡슐화하여 문자열 서브클래싱을 단순화합니다. |
클래스 collections.OrderedDict([항목])
특히 사전 순서를 재정렬하기 위한 메서드가 있는 dict 하위 클래스의 인스턴스를 반환합니다.
3.1 새로운 기능.
popitem(last=True)
정렬 사전의 popitem() 메서드는 (키, 값) 키-값 쌍을 제거하고 반환합니다. 마지막 값이 true이면 키-값 쌍이 LIFO 순서로 반환되고 그렇지 않으면 키-값 쌍이 FIFO 순서로 반환됩니다.
move_to_end(key, last=True)는
기존 키를 정렬된 사전의 끝으로 이동합니다. last가 true(기본값)이면 항목을 오른쪽으로 이동하고 last가 false이면 처음으로 이동합니다. 키가 존재하지 않으면 KeyError 발생:
>>> d = OrderedDict.fromkeys('abcde')
>>> d.move_to_end('b')
>>> ''.join(d)
'acdeb'
>>> d.move_to_end('b', last=False)
>>> ''.join(d)
'bacde'
3.2 새로운 기능.
일반적인 매핑 방법과 비교할 때 순서 사전은 reversed()를 통해 역방향 반복을 추가로 지원합니다.
OrderedDict 사이의 동등성 테스트는 순서에 민감하며 list(od1.items())==list(od2.items()) 로 구현됩니다. OrderedDict 객체 및 기타 매핑에 대한 동등성 테스트는 순서에 민감한 사전 테스트입니다. 이를 통해 사전을 사용할 수 있는 곳에서 OrderedDict를 대체할 수 있습니다.
버전 3.5에서 변경: OrderedDict의 항목, 키 및 값 보기는 이제 reversed()를 통해 역방향 반복을 지원합니다.
버전 3.6에서 변경: PEP 468은 OrderedDict 생성자와 해당 update() 메서드에 전달된 키워드 인수의 순서를 유지하는 것을 선호합니다.
버전 3.9에서 변경: PEP 584 에 설명된 대로 병합(|) 및 업데이트(|=) 연산자를 추가했습니다.
OrderedDict 예제 및 사용법
OrderedDict의 키는 키 자체가 아니라 삽입 순서대로 정렬됩니다.
import collections
print "Regular dictionary"
d={
}
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
print k,v
print "\nOrder dictionary"
d1 = collections.OrderedDict()
d1['a'] = 'A'
d1['b'] = 'B'
d1['c'] = 'C'
d1['1'] = '1'
d1['2'] = '2'
for k,v in d1.items():
print k,v
输出:
Regular dictionary
a A
c C
b B
Order dictionary
a A
b B
c C
1 1
2 2
ABC와 같은 여러 요소도 저장되는 것을 볼 수 있지만 OrderedDict를 사용하면 요소가 배치된 순서에 따라 정렬됩니다. 따라서 출력 값이 정렬됩니다.
OrderedDict 객체의 딕셔너리 객체는 순서가 다른 경우 Python에서 두 객체를 서로 다른 두 객체로 취급합니다. 예를 참조하세요.
print 'Regular dictionary:'
d2={
}
d2['a']='A'
d2['b']='B'
d2['c']='C'
d3={
}
d3['c']='C'
d3['a']='A'
d3['b']='B'
print d2 == d3
print '\nOrderedDict:'
d4=collections.OrderedDict()
d4['a']='A'
d4['b']='B'
d4['c']='C'
d5=collections.OrderedDict()
d5['c']='C'
d5['a']='A'
d5['b']='B'
print d1==d2
输出:
Regular dictionary:
True
OrderedDict:
False
몇 가지 예를 더 살펴보십시오.
dd = {
'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
#按key排序
kd = collections.OrderedDict(sorted(dd.items(), key=lambda t: t[0]))
print kd
#按照value排序
vd = collections.OrderedDict(sorted(dd.items(),key=lambda t:t[1]))
print vd
#输出
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
예제 소개의 이 부분은 도구 시간 에서 전송됩니다.
키가 마지막으로 삽입된 순서를 기억하는 정렬된 사전 변형을 만드는 것은 간단합니다. 새 항목이 기존 항목을 덮어쓰면 원래 삽입 위치가 변경되고 끝으로 이동됩니다.
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)
OrderedDict는 functools.lru_cache()의 변형을 구현하는 데에도 유용합니다.
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(0)
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(0)
else:
self.requests.pop(args, None)
self.cache[args] = result
if len(self.cache) > self.maxsize:
self.cache.popitem(0)
return result