Введение

Встроенный пакет коллекций предоставляет несколько специализированных, гибких типов коллекций, которые одновременно являются высокоэффективными и обеспечивают альтернативы общим типам коллекций dict, list, tuple и set. Модуль также определяет абстрактные базовые классы, описывающие различные типы функциональных возможностей коллекции (такие как MutableSet и ItemsView).

Замечания

В модуле коллекций доступны еще 3 типа, а именно:

  • UserDict
  • UserList
  • UserString

Каждый из них действует как оболочка вокруг связанного объекта, например, UserDict действует как оболочка вокруг объекта типа dict. В каждом случае класс имитирует свой именованный тип. Содержимое экземпляра хранится в объекте обычного типа, доступ к которому осуществляется через атрибут data экземпляра-оболочки. В каждом из этих трех случаев потребность в этих типах была частично вытеснена способностью к подклассу непосредственно из базового типа.

collections.ChainMap


ChainMap - новинка в версии 3.3.  Возвращает новый ChainMap объект с заданным числом карт. Этот объект группирует несколько словарей или других отображений вместе, чтобы создать единое обновляемое представление.

ChainMap’ы полезны для управления вложенными контекстами и наложениями. Пример в мире Python находится в реализации Context класса в шаблонном  движке Джанго. Это полезно для быстрого связывания нескольких отображений, чтобы результат можно было рассматривать как единое целое. Это часто намного быстрее , чем создание нового словаря и запуск несколько update() вызовов.

В любое время, когда у вас имеется цепочка значений поиска, может быть случай для ChainMap. Пример включает в себя наличие заданных пользователем значений и словаря значений по умолчанию. Другим примером являются карты параметров POST и GET найденные в веб - использовании, например, Django или Flask. Благодаря использованию ChainMap можно получить комбинированный представление двух различных словарей.

Список параметров maps организуется от первого-поискового до последнего-поискового. Поисковые запросы последовательно выполняют поиск соответствующих сопоставления, пока не будет найден ключ. Напротив, операции записи, обновления и удаления действуют только при первом сопоставлении.

import collections
# определите 2 словаря с перекрывающимися хотя бы несколькими ключами

dict1 = {'apple': 1, 'banana': 2}
dict2 = {'coconut': 1, 'date': 1, 'apple': 3}

# создайте 2 ChainMap’а с разным порядком этих словарей.
combined_dict = collections.ChainMap(dict1, dict2)
reverse_ordered_dict = collections.ChainMap(dict2, dict1)

Обратите внимание на влияние порядка, в котором значение найдено первым в последующем поиске:

for k, v in combined_dict.items():
    print(k, v)

>>>Out: coconut 1
	date 1
	apple 1
    	banana 2

for k, v in reverse_ordered_dict.items():
    print(k, v)

>>>Out: apple 3
	banana 2
    	coconut 1

collections.Counter

Счетчик является подклассом словаря , что позволяет легко считать объекты. У него есть полезные методы для работы с частотностью объектов, которые вы считаете.

import collections
counts = collections.Counter([1,2,3]) 

Приведенный выше код создает объект count, который имеет частоты всех элементов, передаваемых в конструктор. Этот пример имеет значение Counter({1: 1, 2: 1, 3: 1})

Примеры конструктора

Счетчик символов

collections.Counter('Happy Birthday')

>>>Out: Counter({'H': 1,
         'a': 2,
         'p': 2,
         'y': 2,
         ' ': 1,
         'B': 1,
         'i': 1,
         'r': 1,
         't': 1,
         'h': 1,
         'd': 1})

Счетчик слов

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())

>>>Out: Counter({'I': 3,
         'am': 2,
         'Sam': 2,
         'That': 2,
         'Sam-I-am': 2,
         'Sam-I-am!': 1,
         'do': 1,
         'not': 1,
         'like': 1,
         'that': 1})

 

Рецепты

c = collections.Counter({'a': 4, 'b': 2, 'c': -2, 'd': 0})

Получить количество отдельных элементов

c['a']

>>>Out: 4

Установить количество отдельных элементов

c['c'] = -3
c

>>>Out: Counter({'a': 4, 'b': 2, 'd': 0, 'c': -3})

Получить общее количество элементов в счетчике (4 + 2 + 0 - 3)

sum(c.values())  #отрицательные числа считаются!

>>>Out: 3

Получить элементы (сохраняются только элементы с положительным счетчиком)

list(c.elements())

>>>Out: ['a', 'a', 'a', 'a', 'b', 'b']

Удалить ключи с 0 или отрицательным значением

c - collections.Counter()

>>>Counter({'a': 4, 'b': 2})

 

Удалить все

c.clear()
c
>>>Out: Counter()

Добавить удалить отдельные элементы

c.update({'a': 3, 'b':3})
c.update({'a': 2, 'c':2})  # добавление к существующему, устанавливает если не существует
c

>>>Out: Counter({'a': 5, 'b': 3, 'c': 2})

c.subtract({'a': 3, 'b': 3, 'c': 3})  # вычитание (неготивные значения разрешены)
c

>>>Out: Counter({'a': 2, 'b': 0, 'c': -1})

collections.defaultdict

collections.defaultdict (default_factory) возвращает подкласс dict, который имеет значение по умолчанию для отсутствующих ключей. Аргумент должен быть функцией, которая возвращает значение по умолчанию при вызове без аргументов. Если нет ничего прошло, по умолчанию None .

state_capitals = collections.defaultdict(str)
state_capitals
>>>Out: defaultdict(str, {})

возвращает ссылку на defaultdict, который создаст строковый объект с его методом default_factory.

Типичное использование defaultdict это использовать один из встроенных типов , такие как str , int , list или dict как default_factory, так как они возвращают пустые типы при вызове без аргументов:

str()

>>>Out: ''

int()

>>>Out: 0

list()
>>>Out: []


 

Вызов defaultdict с ключом, который не существует, не приводит к ошибке, как в обычном словаре.

state_capitals['Alaska']

>>>Out: ''

state_capitals

>>>Out: defaultdict(str, {'Alaska': ''})

Другой пример с int :

fruit_counts = collections.defaultdict(int)
fruit_counts['apple'] += 2  # No errors should occur
fruit_counts

>>>Out: defaultdict(int, {'apple': 2})

fruit_counts['banana']  # No errors should occur

>>>Out: 0

fruit_counts  # A new key is created

>>>Out: default_dict(int, {'apple': 2, 'banana': 0}) 

Обычные словарные методы работают со словарем по умолчанию

 >>> state_capitals['Alabama'] = 'Montgomery'
>>> state_capitals
defaultdict(<class 'str'>, {'Alabama': 'Montgomery', 'Alaska': ''})

 

Использование list в качестве default_factory создаст список для каждого нового ключа.

 >>> 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.OrderedDict

Порядок ключей в словарях Python произвольный: они не регулируются порядком их добавления.

Например:

 >>> 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}
```

 

(Произвольный порядок, подразумеваемый выше, означает, что вы можете получить результаты с кодом выше, чем показано здесь.)

Порядок , в котором появляются ключи есть порядок , который они будут повторяться в течение, например , с использованием for петли.

collections.OrderedDict класс предоставляет объекты словаря , которые сохраняют порядок ключей. OrderedDict s могут быть созданы , как показано ниже , с серией упорядоченных элементов (здесь, список пар кортежей ключ-значение):

 >>> 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)])

 

Или мы можем создать пустой OrderedDict , а затем добавить элементы:

 >>> o = OrderedDict()
>>> o['key1'] = "value1"
>>> o['key2'] = "value2"
>>> print(o)
OrderedDict([('key1', 'value1'), ('key2', 'value2')])

 

Итерация через OrderedDict позволяет доступ к ключам в порядке их добавления.

Что произойдет, если мы присвоим новое значение существующему ключу?

 >>> d['foo'] = 4
>>> print(d)
OrderedDict([('foo', 4), ('bar', 6), ('baz', 7), ('foobar', 8)])

 

Ключ сохраняет свое первоначальное место в OrderedDict .

collections.namedtuple

Определение нового типа Person с использованием namedtuple , как это:

 Person = namedtuple('Person', ['age', 'height', 'name'])

 

Второй аргумент - это список атрибутов, которые будет иметь кортеж. Вы можете перечислить эти атрибуты также в виде строки, разделенной пробелами или запятыми:

 Person = namedtuple('Person', 'age, height, name')

 

или же

 Person = namedtuple('Person', 'age height name')

 

После определения именованного кортежа можно создать экземпляр, вызвав объект с необходимыми параметрами, например:

 dave = Person(30, 178, 'Dave')

 

Именованные аргументы также могут быть использованы:

 jack = Person(age=30, height=178, name='Jack S.')

 

Теперь вы можете получить доступ к атрибутам namedtuple:

 print(jack.age)  # 30
print(jack.name)  # 'Jack S.'


 

Первый аргумент namedtuple конструктора (в нашем примере 'Person' ) является typename . Типично использовать одно и то же слово для конструктора и имя типа, но они могут быть разными:

 Human = namedtuple('Person',  'age, height, name')
dave = Human(30, 178, 'Dave')
print(dave)  # yields: Person(age=30, height=178, name='Dave')

 

collections.deque

Возвращает новый deque объект инициализируется слева направо ( с помощью добавления ()) с данными Iterable. Если итератор не указан, новый deque пуст.

Deques - это обобщение стеков и очередей (название произносится как «колода» и сокращенно означает «двусторонняя очередь»). Поддержка двусторонних очереди потокобезопасная, память и эффективные присоединяют хлопки из обоего сторон deque с приблизительно таким же O (1) производительностью в любом направлении.

Хотя объекты списка поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и требуют O (n) затрат на перемещение памяти для операций pop (0) и insert (0, v), которые изменяют как размер, так и позицию базового представления данных. ,

Новое в версии 2.4.

Если maxlen не указаны или не None , могут вырасти двусторонние очереди до произвольной длины. В противном случае, deque ограничена до заданной максимальной длины. После того, как ограниченная длина deque полна, когда добавляются новые элементы, соответствующее количество элементов, отбрасываются с противоположного конца. Запросы ограниченной длины обеспечивают функциональность, аналогичную хвостовому фильтру в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляют только самые последние действия.

Изменено в версии 2.6: добавлен параметр 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'])

 

Источник: https://docs.python.org/2/library/collections.html

collections.ChainMap

ChainMap нового в версии 3.3

Возвращает новый ChainMap объект дал ряд maps . Этот объект группирует несколько диктовок или других отображений вместе, чтобы создать единое обновляемое представление.

ChainMap s полезны управления вложенными контекстами и наложений. Пример в питона мире находится в реализации Context класса в шаблонизаторе Джанго. Это полезно для быстрого связывания нескольких отображений, чтобы результат можно было рассматривать как единое целое. Это часто намного быстрее , чем создание нового словаря и запуск несколько update() вызовов.

В любое время один имеет цепочку значений подстановки может быть случай для ChainMap . Пример включает в себя наличие заданных пользователем значений и словаря значений по умолчанию. Другим примером является POST и GET карты параметров найдены в веб - использования, например , Django или флягу. Благодаря использованию ChainMap один возвращает комбинированный вид двух различных словарей.

maps список параметров заказывается из первых обыскали в последний раз обыскали. Поиски последовательно выполняют поиск соответствующих отображений, пока не будет найден ключ. Напротив, операции записи, обновления и удаления действуют только при первом сопоставлении.

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)

 

Обратите внимание на влияние порядка, в котором значение найдено первым в последующем поиске

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 

Синтаксис

Параметры

Примечания