Python 표준 라 이브 러 리 의 collections 패키지 사용 튜 토리 얼
14474 단어 pythoncollections표준 라 이브 러 리
Python 은 우리 에 게 4 가지 기본 적 인 데이터 구 조 를 제공 했다.list,tuple,dict,set.그러나 데이터 양 이 비교적 많은 상황 을 처리 할 때 이 4 가지 데이터 구 조 는 현저히 단일 하 다.예 를 들 어 list 는 배열 로 서 특정한 상황 에 삽입 하 는 효율 이 비교적 낮 고 가끔 은 우리 도 질서 있 는 dict 를 유지 해 야 한다.그래서 이 럴 때 우 리 는 Python 표준 라 이브 러 리 를 사용 하여 우리 에 게 제공 하 는 collection s 가방 을 사용 해 야 합 니 다.이것 은 여러 개의 유용 한 집합 류 를 제공 합 니 다.이런 집합 류 를 능숙 하 게 파악 하면 우리 가 쓴 코드 를 더욱 Python 으로 만 들 수 있 을 뿐만 아니 라 우리 프로그램의 운행 효율 도 높 일 수 있 습 니 다.
defaultdict
defaultdict(default_factory)
일반적인 dict 에 default 를 추가 하 였 습 니 다.factory,key 가 존재 하지 않 을 때 해당 유형의 value,default 를 자동 으로 생 성 합 니 다.factory 매개 변 수 는 list,set,int 등 각종 합 법 적 인 유형 으로 지정 할 수 있 습 니 다.우 리 는 현재 다음 과 같은 list 가 있 습 니 다.비록 우 리 는 5 개의 데 이 터 를 가지 고 있 지만 자세히 관찰 한 결과 우 리 는 3 가지 color 만 있 지만 모든 color 는 여러 개의 값 에 대응 합 니 다.현재 이 list 를 dict 로 변환 하려 고 합 니 다.이 dict 의 key 는 하나의 color 에 대응 하고 dict 의 value 는 하나의 list 로 color 에 대응 하 는 여러 값 을 저장 합 니 다.우 리 는 이 문 제 를 해결 하기 위해
defaultdict(list)
를 사용 할 수 있다.
>>> from collections import defaultdict
>>> 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])]
이상 등가:
>>> d = {}
>>> for k, v in s:
... d.setdefault(k, []).append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
만약 우리 가 중복 되 는 요 소 를 포함 하고 싶 지 않다 면 사용 을 고려 할 수 있다defaultdict(set)
.set 가 list 에 비해 다른 점 은 set 에 같은 요소 가 존재 하지 않 는 다 는 것 입 니 다.
>>> from collections import 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})]
OrderedDictPython 3.6 이전의 dict 는 무질서 하 였 으 나,어떤 경우 에는 dict 의 질서 성 을 유지 해 야 합 니 다.이 럴 때 OrderedDict 를 사용 할 수 있 습 니 다.이것 은 dict 의 subclass 이지 만,dict 를 바탕 으로 dict 의 질서 형 을 유지 하 였 습 니 다.다음은 사용 방법 을 살 펴 보 겠 습 니 다.
>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
>>> # dictionary sorted by key
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
popitem(last=True)
방법 을 사용 하면 LIFO(선진 후 출)순서에 따라 dict 의 key-value 를 삭제 할 수 있 습 니 다.즉,마지막 으로 삽 입 된 키 쌍 을 삭제 합 니 다.last=False 는 FIFO(선진 선 출)에 따라 dict 의 key-value 를 삭제 합 니 다.
>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
>>> # dictionary sorted by key
>>> d = OrderedDict(sorted(d.items(), key=lambda t: t[0]))
>>> d
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> d.popitem()
('pear', 1)
>>> d.popitem(last=False)
('apple', 4)
move_to_end(key, last=True)
를 사용 하여 질서 있 는 OrderedDict 대상 의 key-value 순 서 를 바 꿉 니 다.이 방법 을 통 해 정렬 된 OrderedDict 대상 중의 임의의 key-value 를 사전 의 시작 이나 끝 에 삽입 할 수 있 습 니 다.
>>> d = OrderedDict.fromkeys('abcde')
>>> d
OrderedDict([('a', None), ('b', None), ('c', None), ('d', None), ('e', None)])
>>> d.move_to_end('b')
>>> d
OrderedDict([('a', None), ('c', None), ('d', None), ('e', None), ('b', None)])
>>> ''.join(d.keys())
'acdeb'
>>> d.move_to_end('b', last=False)
>>> ''.join(d.keys())
'bacde'
dequelist 에 데 이 터 를 저장 하 는 장점 은 색인 에 따라 요 소 를 찾 는 것 이 빠 르 지만 요 소 를 삽입 하고 삭제 하 는 것 이 느 립 니 다.list 는 배열 을 바탕 으로 이 루어 지기 때 문 입 니 다.deque 는 삽입 과 삭 제 를 위 한 양 방향 목록 으로 대기 열 과 스 택 에 적합 하 며 스 레 드 가 안전 합 니 다.
list 는 append 와 pop 방법 만 제공 하여 list 의 끝 부분 에서 요 소 를 삽입/삭제 합 니 다.deque 는 appendleft/opleft 등 방법 을 추가 하여 요소 의 시작 부분 에 요 소 를 삽입/삭제 할 수 있 도록 합 니 다.또한 deque 를 사용 하여 대기 열 양쪽 에 있 는 append 나 pop 요 소 를 사용 하 는 알고리즘 의 복잡 도 는 대략 O(1)이지 만 list 대상 이 목록 의 길이 와 데이터 위 치 를 바 꾸 는 작업,예 를 들 어
pop(0)
와insert(0, v)
작업 의 복잡 도 는 O(n)에 달한다.
>>> from collections import deque
>>> dq = deque(range(10), maxlen=10)
>>> dq
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> dq.rotate(3)
>>> dq
deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10)
>>> dq.rotate(-4)
>>> dq
deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10)
>>> dq.appendleft(-1)
>>> dq
deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> dq.extend([11, 22, 33])
>>> dq
deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33], maxlen=10)
>>> dq.extendleft([10, 20, 30, 40])
>>> dq
deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8], maxlen=10)
CounterCount 는 관련 요소 의 출현 횟수 를 통계 하 는 데 쓰 인 다.
>>> from collections import Counter
>>> ct = Counter('abracadabra')
>>> ct
Counter({'a': 5, 'r': 2, 'b': 2, 'd': 1, 'c': 1})
>>> ct.update('aaaaazzz')
>>> ct
Counter({'a': 10, 'z': 3, 'r': 2, 'b': 2, 'd': 1, 'c': 1})
>>> ct.most_common(2)
[('a', 10), ('z', 3)]
>>> ct.elements()
<itertools.chain object at 0x7fbaad4b44e0>
namedtuplenamedtuple(typename, field_names)
tuple 의 요 소 를 사용 하여 프로그램 을 더욱 읽 을 수 있 도록 합 니 다.
>>> from collections import namedtuple
>>> City = namedtuple('City', 'name country population coordinates')
>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
>>> tokyo
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
>>> tokyo.population
36.933
>>> tokyo.coordinates
(35.689722, 139.691667)
>>> tokyo[1]
'JP'
>>> City._fields
('name', 'country', 'population', 'coordinates')
>>> LatLong = namedtuple('LatLong', 'lat long')
>>> delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
>>> delhi = City._make(delhi_data)
>>> delhi._asdict()
OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 21.935),
('coordinates', LatLong(lat=28.613889, long=77.208889))])
>>> for key, value in delhi._asdict().items():
print(key + ':', value)
name: Delhi NCR
country: IN
population: 21.935
coordinates: LatLong(lat=28.613889, long=77.208889)
ChainMapChainMap 은 여러 사전 을 통합 하 는 데 사용 할 수 있 습 니 다.
>>> from collections import ChainMap
>>> d = ChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})
>>> d['lion'] = 'orange'
>>> d['snake'] = 'red'
>>> d
ChainMap({'lion': 'orange', 'zebra': 'black', 'snake': 'red'},
{'elephant': 'blue'}, {'lion': 'yellow'})
>>> del d['lion']
>>> del d['elephant']
Traceback (most recent call last):
File "/usr/lib/python3.5/collections/__init__.py", line 929, in __delitem__
del self.maps[0][key]
KeyError: 'elephant'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/collections/__init__.py", line 931, in __delitem__
raise KeyError('Key not found in the first mapping: {!r}'.format(key))
KeyError: "Key not found in the first mapping: 'elephant'"
위del['elephant']
의 오류 정 보 를 통 해 알 수 있 듯 이 키 값 을 바 꾸 는 조작 ChainMap 은 첫 번 째 사전self.maps[0][key]
에서 만 찾 을 수 있 습 니 다.새로 추 가 된 키 값 쌍 도 첫 번 째 사전 에 추 가 됩 니 다.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
DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})
new 사용 가능child 래 deepcopy 체인 맵:
>>> from collections import ChainMap
>>> a = {'a': 'A', 'c': 'C'}
>>> b = {'b': 'B', 'c': 'D'}
>>> m = ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
>>> m
ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
>>> m['c']
'C'
>>> m.maps
[{'c': 'C', 'a': 'A'}, {'c': 'D', 'b': 'B'}]
>>> a['c'] = 'E'
>>> m['c']
'E'
>>> m
ChainMap({'c': 'E', 'a': 'A'}, {'c': 'D', 'b': 'B'})
>>> m2 = m.new_child()
>>> m2['c'] = 'f'
>>> m2
ChainMap({'c': 'f'}, {'c': 'E', 'a': 'A'}, {'c': 'D', 'b': 'B'})
>>> m
ChainMap({'c': 'E', 'a': 'A'}, {'c': 'D', 'b': 'B'})
>>> m2.parents
ChainMap({'c': 'E', 'a': 'A'}, {'c': 'D', 'b': 'B'})
UserDict사전 을 개선 하고 사전 을 조회 할 때 key 를 str 형식 으로 변환 합 니 다.
class StrKeyDict0(dict):
def __missing__(self, key):
if isinstance(key, str):
raise KeyError(key)
return self[str(key)]
def get(self, key, default=None):
try:
return self[key]
except KeyError:
return default
def __contains__(self, key):
return key in self.keys() or str(key) in self.keys()
위의 프로그램 을 설명 하 십시오.k in my_dict
.왜냐하면str(key) in self
의 형식 은 재 귀 호출contains__。위의 이 예 는 UserDict 로 고 칠 수 있 고 모든 key 를 str 형식 으로 저장 할 수 있 으 며 이런 쓰기 방법 은 더욱 간결 하 다.
import collections
class StrKeyDict(collections.UserDict):
def __missing__(self, key):
if isinstance(key, str):
raise KeyError(key)
return self[str(key)]
def __contains__(self, key):
return str(key) in self.data
def __setitem__(self, key, item):
self.data[str(key)] = item
UserDict 는 Mutable Mapping 과 Mapping 의 하위 클래스 로 Mutable Mapping.update 와 Mapping.get 두 가지 중요 한 방법 을 계승 하 였 기 때문에 위 에서 get 방법 을 다시 쓰 지 않 았 습 니 다.소스 코드에서 그의 실현 과 우리 위의 실현 은 차이 가 많 지 않 습 니 다.총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.