Python Language
Moduł kolekcji
Szukaj…
Wprowadzenie
Wbudowany pakiet collections
udostępnia kilka specjalistycznych, elastycznych typów kolekcji, które są zarówno wydajne, jak i stanowią alternatywę dla ogólnych typów kolekcji, takich jak dict
, list
, tuple
i set
. Moduł definiuje również abstrakcyjne klasy podstawowe opisujące różne typy funkcji kolekcji (takie jak MutableSet
i ItemsView
).
Uwagi
Istnieją trzy inne typy dostępne w module kolekcji , a mianowicie:
- UserDict
- Lista użytkowników
- UserString
Każdy z nich działa jak owinięcie wokół powiązanego obiektu, np. UserDict działa jak owinięcie wokół obiektu dict . W każdym przypadku klasa symuluje swój nazwany typ. Treść instancji jest przechowywana w obiekcie regularnego typu, który jest dostępny poprzez atrybut danych instancji opakowania. W każdym z tych trzech przypadków zapotrzebowanie na te typy zostało częściowo wyparte przez możliwość podklasy bezpośrednio z typu podstawowego; jednak z klasą opakowania można łatwiej pracować, ponieważ typ bazowy jest dostępny jako atrybut.
kolekcje. licznik
Licznik to podklasa dict, która umożliwia łatwe liczenie obiektów. Ma użyteczne metody pracy z częstotliwościami liczonych obiektów.
import collections
counts = collections.Counter([1,2,3])
powyższy kod tworzy obiekt, liczy, który ma częstotliwości wszystkich elementów przekazywanych do konstruktora. Ten przykład ma wartość Counter({1: 1, 2: 1, 3: 1})
Przykłady konstruktorów
Licznik listów
>>> collections.Counter('Happy Birthday')
Counter({'a': 2, 'p': 2, 'y': 2, 'i': 1, 'r': 1, 'B': 1, ' ': 1, 'H': 1, 'd': 1, 'h': 1, 't': 1})
Licznik słów
>>> collections.Counter('I am Sam Sam I am That Sam-I-am That Sam-I-am! I do not like that Sam-I-am'.split())
Counter({'I': 3, 'Sam': 2, 'Sam-I-am': 2, 'That': 2, 'am': 2, 'do': 1, 'Sam-I-am!': 1, 'that': 1, 'not': 1, 'like': 1})
Przepisy
>>> c = collections.Counter({'a': 4, 'b': 2, 'c': -2, 'd': 0})
Oblicz liczbę poszczególnych elementów
>>> c['a']
4
Ustaw liczbę poszczególnych elementów
>>> c['c'] = -3
>>> c
Counter({'a': 4, 'b': 2, 'd': 0, 'c': -3})
Uzyskaj całkowitą liczbę elementów w liczniku (4 + 2 + 0 - 3)
>>> sum(c.itervalues()) # negative numbers are counted!
3
Zdobądź elementy (tylko te z dodatnim licznikiem są przechowywane)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
Usuń klucze z 0 lub wartością ujemną
>>> c - collections.Counter()
Counter({'a': 4, 'b': 2})
Usuń wszystko
>>> c.clear()
>>> c
Counter()
Dodaj usuń poszczególne elementy
>>> c.update({'a': 3, 'b':3})
>>> c.update({'a': 2, 'c':2}) # adds to existing, sets if they don't exist
>>> c
Counter({'a': 5, 'b': 3, 'c': 2})
>>> c.subtract({'a': 3, 'b': 3, 'c': 3}) # subtracts (negative values are allowed)
>>> c
Counter({'a': 2, 'b': 0, 'c': -1})
collections.defaultdict
collections.defaultdict (default_factory) zwraca podklasę dict
która ma domyślną wartość dla brakujących kluczy. Argument powinien być funkcją, która zwraca domyślną wartość po wywołaniu bez argumentów. Jeśli nic nie zostanie przekazane, domyślnie ustawiony jest None
.
>>> state_capitals = collections.defaultdict(str)
>>> state_capitals
defaultdict(<class 'str'>, {})
zwraca odwołanie do defaultdict, który utworzy obiekt łańcuchowy za pomocą metody default_factory.
Typowe użycie defaultdict
polega na użyciu jednego z wbudowanych typów, takich jak str
, int
, list
lub dict
jako default_factory, ponieważ te zwracają puste typy, gdy są wywoływane bez argumentów:
>>> str()
''
>>> int()
0
>>> list
[]
Wywołanie defaultdict z kluczem, który nie istnieje, nie powoduje błędu, tak jak w normalnym słowniku.
>>> state_capitals['Alaska']
''
>>> state_capitals
defaultdict(<class 'str'>, {'Alaska': ''})
Kolejny przykład z int
:
>>> fruit_counts = defaultdict(int)
>>> fruit_counts['apple'] += 2 # No errors should occur
>>> fruit_counts
default_dict(int, {'apple': 2})
>>> fruit_counts['banana'] # No errors should occur
0
>>> fruit_counts # A new key is created
default_dict(int, {'apple': 2, 'banana': 0})
Normalne metody słownikowe działają ze słownikiem domyślnym
>>> state_capitals['Alabama'] = 'Montgomery'
>>> state_capitals
defaultdict(<class 'str'>, {'Alabama': 'Montgomery', 'Alaska': ''})
Użycie list
jako fabryki domyślnej spowoduje utworzenie listy dla każdego nowego klucza.
>>> s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')]
>>> dd = collections.defaultdict(list)
>>> for k, v in s:
... dd[k].append(v)
>>> dd
defaultdict(<class 'list'>,
{'VA': ['Richmond'],
'NC': ['Raleigh', 'Asheville'],
'WA': ['Seattle']})
collections.OrDERDict
Kolejność kluczy w słownikach Pythona jest dowolna: nie podlegają one kolejności dodawania.
Na przykład:
>>> d = {'foo': 5, 'bar': 6}
>>> print(d)
{'foo': 5, 'bar': 6}
>>> d['baz'] = 7
>>> print(a)
{'baz': 7, 'foo': 5, 'bar': 6}
>>> d['foobar'] = 8
>>> print(a)
{'baz': 7, 'foo': 5, 'bar': 6, 'foobar': 8}
```
(Sugerowane powyżej arbitralne porządkowanie oznacza, że możesz uzyskać inne wyniki z powyższym kodem niż pokazany tutaj.)
Kolejność pojawiania się kluczy to kolejność, w jakiej byłyby iterowane, np. Za pomocą pętli for
.
Klasa collections.OrderedDict
udostępnia obiekty słownikowe, które zachowują kolejność kluczy. OrderedDict
s można utworzyć, jak pokazano poniżej, z serią uporządkowanych przedmiotów (tutaj lista krotek par klucz-wartość):
>>> from collections import OrderedDict
>>> d = OrderedDict([('foo', 5), ('bar', 6)])
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6)])
>>> d['baz'] = 7
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6), ('baz', 7)])
>>> d['foobar'] = 8
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6), ('baz', 7), ('foobar', 8)])
Lub możemy utworzyć pusty OrderedDict
a następnie dodać elementy:
>>> o = OrderedDict()
>>> o['key1'] = "value1"
>>> o['key2'] = "value2"
>>> print(o)
OrderedDict([('key1', 'value1'), ('key2', 'value2')])
OrderedDict
za pomocą polecenia OrderedDict
umożliwia dostęp do klucza w kolejności, w jakiej zostały dodane.
Co się stanie, jeśli przypisamy nową wartość do istniejącego klucza?
>>> d['foo'] = 4
>>> print(d)
OrderedDict([('foo', 4), ('bar', 6), ('baz', 7), ('foobar', 8)])
Klucz zachowuje swoje pierwotne miejsce w OrderedDict
.
collections.namedtuple
Zdefiniuj nowy typ Person
za pomocą namedtuple
następujący sposób:
Person = namedtuple('Person', ['age', 'height', 'name'])
Drugi argument to lista atrybutów, które będzie miała krotka. Możesz wymienić te atrybuty również jako ciąg oddzielony spacją lub przecinkiem:
Person = namedtuple('Person', 'age, height, name')
lub
Person = namedtuple('Person', 'age height name')
Po zdefiniowaniu można utworzyć instancję nazwanej krotki, wywołując obiekt z niezbędnymi parametrami, np .:
dave = Person(30, 178, 'Dave')
Można także użyć nazwanych argumentów:
jack = Person(age=30, height=178, name='Jack S.')
Teraz możesz uzyskać dostęp do atrybutów namedtuple:
print(jack.age) # 30
print(jack.name) # 'Jack S.'
Pierwszym argumentem konstruktora namedtuple (w naszym przykładzie 'Person'
) jest typename
. Typowe jest używanie tego samego słowa dla konstruktora i nazwy typu, ale mogą być one różne:
Human = namedtuple('Person', 'age, height, name')
dave = Human(30, 178, 'Dave')
print(dave) # yields: Person(age=30, height=178, name='Dave')
collections.deque
Zwraca nowy obiekt deque
zainicjowany od lewej do prawej (za pomocą append ()) z danymi z iteracji. Jeśli iterable nie jest określony, nowy deque
jest pusty.
Deques są uogólnieniem stosów i kolejek (nazwa jest wymawiana jako „talia” i jest skrótem od „podwójnie zakończonej kolejki”). Deques obsługują bezpieczne dla wątków, wydajne pamięci dołącza i wyskakuje z każdej strony deque
z mniej więcej taką samą wydajnością O (1) w obu kierunkach.
Chociaż obiekty listy obsługują podobne operacje, są one zoptymalizowane pod kątem szybkich operacji o stałej długości i ponoszą koszty ruchu pamięci O (n) dla operacji pop (0) i insert (0, v), które zmieniają zarówno rozmiar, jak i położenie reprezentacji danych podstawowych .
Nowości w wersji 2.4.
Jeśli maxlen
nie jest określony lub ma wartość None
, deques mogą wzrosnąć do dowolnej długości. W przeciwnym razie deque
jest ograniczone do określonej maksymalnej długości. Gdy deque
z ograniczoną długością jest pełny, gdy dodawane są nowe przedmioty, odpowiadająca ich liczba jest odrzucana z przeciwnego końca. Deques o ograniczonej długości zapewniają funkcjonalność podobną do filtra ogona w Uniksie. Są one również przydatne do śledzenia transakcji i innych pul danych, w których interesująca jest tylko najnowsza aktywność.
Zmieniono w wersji 2.6: Dodano parametr maxlen.
>>> 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'])
Źródło: https://docs.python.org/2/library/collections.html
collections.ChainMap
ChainMap
jest nowy w wersji 3.3
Zwraca nowy obiekt ChainMap
podstawie wielu maps
. Ten obiekt grupuje wiele nagrań lub innych mapowań razem, tworząc pojedynczy, aktualizowany widok.
ChainMap
s przydatne do zarządzania zagnieżdżonymi kontekstami i nakładkami. Przykład w świecie python znajduje się w implementacji klasy Context
w silniku szablonów Django. Jest to przydatne do szybkiego łączenia wielu mapowań, dzięki czemu wynik może być traktowany jako pojedyncza jednostka. Często jest to znacznie szybsze niż tworzenie nowego słownika i uruchamianie wielu wywołań update()
.
Za każdym razem, gdy istnieje łańcuch wartości wyszukiwania, może istnieć przypadek ChainMap
. Przykład obejmuje zarówno wartości określone przez użytkownika, jak i słownik wartości domyślnych. Innym przykładem są mapy parametrów POST
i GET
znalezione w sieci, np. Django lub Flask. Dzięki zastosowaniu ChainMap
zwraca się widok dwóch odrębnych słowników.
Lista parametrów maps
jest uporządkowana od pierwszego do ostatniego wyszukiwania. Wyszukiwanie przeszukuje podstawowe mapowania sukcesywnie, aż do znalezienia klucza. Natomiast zapisy, aktualizacje i usunięcia działają tylko przy pierwszym mapowaniu.
import collections
# define two dictionaries with at least some keys overlapping.
dict1 = {'apple': 1, 'banana': 2}
dict2 = {'coconut': 1, 'date': 1, 'apple': 3}
# create two ChainMaps with different ordering of those dicts.
combined_dict = collections.ChainMap(dict1, dict2)
reverse_ordered_dict = collections.ChainMap(dict2, dict1)
Zwróć uwagę na wpływ kolejności, w której wartość zostanie znaleziona jako pierwsza w kolejnym wyszukiwaniu
for k, v in combined_dict.items():
print(k, v)
date 1
apple 1
banana 2
coconut 1
for k, v in reverse_ordered_dict.items():
print(k, v)
date 1
apple 3
banana 2
coconut 1