Ricerca…


introduzione

Il pacchetto di collections integrato offre diversi tipi di raccolta flessibili e specializzati che sono sia ad alte prestazioni che forniscono alternative ai tipi di raccolta generale di dict , list , tuple e set . Il modulo definisce anche classi di base astratte che descrivono diversi tipi di funzionalità di raccolta (come MutableSet e ItemsView ).

Osservazioni

Ci sono altri tre tipi disponibili nel modulo raccolte , vale a dire:

  1. UserDict
  2. Lista degli utenti
  3. UserString

Ognuno di essi funge da involucro attorno all'oggetto legato, ad esempio UserDict funge da involucro attorno a un oggetto dict . In ogni caso, la classe simula il suo tipo con nome. I contenuti dell'istanza sono conservati in un oggetto di tipo regolare, accessibile tramite l'attributo data dell'istanza wrapper. In ciascuno di questi tre casi, la necessità di questi tipi è stata parzialmente soppiantata dalla possibilità di sottoclasse direttamente dal tipo di base; tuttavia, la classe wrapper può essere più semplice da utilizzare perché il tipo sottostante è accessibile come attributo.

collections.Counter

Counter è una sottoclasse di dict che consente di contare facilmente gli oggetti. Ha metodi di utilità per lavorare con le frequenze degli oggetti che si stanno contando.

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

il codice precedente crea un oggetto, conteggi, che ha le frequenze di tutti gli elementi passati al costruttore. Questo esempio ha il valore Counter({1: 1, 2: 1, 3: 1})

Esempi di costruttore

Contatore di lettere

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

Contatore di parole

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

ricette

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

Ottieni il conteggio dei singoli elementi

>>> c['a']
4

Imposta il conteggio del singolo elemento

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

Ottieni il numero totale di elementi nel contatore (4 + 2 + 0 - 3)

>>> sum(c.itervalues())  # negative numbers are counted!
3

Ottieni elementi (vengono mantenuti solo quelli con contatore positivo)

>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']

Rimuovi le chiavi con 0 o valore negativo

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

Rimuovi tutto

>>> c.clear()
>>> c
Counter()

Aggiungi rimuovi singoli elementi

>>> 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) restituisce una sottoclasse di dict che ha un valore predefinito per le chiavi mancanti. L'argomento dovrebbe essere una funzione che restituisce il valore predefinito quando viene chiamato senza argomenti. Se non viene passato nulla, il valore predefinito è None .

>>> state_capitals = collections.defaultdict(str)
>>> state_capitals
defaultdict(<class 'str'>, {})

restituisce un riferimento ad un defaultdict che creerà un oggetto stringa con il suo metodo default_factory.

Un tipico uso di defaultdict è di usare uno dei tipi builtin come str , int , list o dict come default_factory, poiché restituiscono tipi vuoti quando vengono chiamati senza argomenti:

>>> str()
''
>>> int()
0
>>> list
[]

Chiamare il defaultdict con una chiave che non esiste non produce un errore come farebbe in un normale dizionario.

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

Un altro esempio con 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})

I metodi di dizionario normali funzionano con il dizionario predefinito

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

Usando list come default_factory creerai un elenco per ogni nuova chiave.

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

L'ordine delle chiavi nei dizionari Python è arbitrario: non sono regolati dall'ordine in cui vengono aggiunti.

Per esempio:

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

(L'ordinamento arbitrario implicito sopra significa che potresti ottenere risultati diversi con il codice sopra a quello mostrato qui.)

L'ordine in cui appaiono le chiavi è l'ordine su cui verrebbero ripetuti, ad esempio utilizzando un ciclo for .

La classe collections.OrderedDict fornisce oggetti dizionario che mantengono l'ordine delle chiavi. OrderedDict s può essere creato come mostrato di seguito con una serie di elementi ordinati (qui, un elenco di coppie chiave-valore di tuple):

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

Oppure possiamo creare un OrderedDict vuoto e quindi aggiungere elementi:

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

L'iterazione di un OrderedDict consente l'accesso tramite chiave nell'ordine in cui sono stati aggiunti.

Cosa succede se assegniamo un nuovo valore a una chiave esistente?

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

La chiave mantiene il suo posto originale in OrderedDict .

collections.namedtuple

Definisci un nuovo tipo Person usa namedtuple questo modo:

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

Il secondo argomento è l'elenco degli attributi che avrà la tupla. È possibile elencare questi attributi anche come stringa separata o separata da virgole:

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

o

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

Una volta definita, una tupla con nome può essere istanziata chiamando l'oggetto con i parametri necessari, ad esempio:

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

Gli argomenti con nome possono anche essere usati:

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

Ora puoi accedere agli attributi di namedtuple:

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

Il primo argomento del costruttore namedtuple (nel nostro esempio 'Person' ) è il typename . È tipico usare la stessa parola per il costruttore e il typename, ma possono essere diversi:

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

collections.deque

Restituisce un nuovo oggetto deque inizializzato da sinistra a destra (usando append ()) con i dati da iterable. Se iterable non è specificato, il nuovo deque è vuoto.

Deques sono una generalizzazione di stack e code (il nome è pronunciato "deck" ed è l'abbreviazione di "double-ended queue"). I Deques supportano gli accessi e gli schiocchi a prova di thread ed efficienza da entrambi i lati della deque con approssimativamente le stesse prestazioni O (1) in entrambe le direzioni.

Sebbene gli oggetti elenco supportino operazioni simili, sono ottimizzati per operazioni veloci a lunghezza fissa e sostengono costi di spostamento della memoria O (n) per operazioni pop (0) e insert (0, v) che cambiano sia la dimensione che la posizione della rappresentazione sottostante dei dati .

Novità nella versione 2.4.

Se maxlen non è specificato o è None , i deques possono raggiungere una lunghezza arbitraria. Altrimenti, la deque è limitata alla lunghezza massima specificata. Quando una deque lunghezza limitata è piena, quando vengono aggiunti nuovi elementi, un numero corrispondente di elementi viene scartato dall'estremità opposta. Gli accessori di lunghezza limitata offrono funzionalità simili al filtro di coda in Unix. Sono anche utili per tracciare le transazioni e altri pool di dati in cui interessa solo l'attività più recente.

Modificato nella versione 2.6: Aggiunto il parametro 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'])

Fonte: https://docs.python.org/2/library/collections.html

collections.ChainMap

ChainMap è nuovo nella versione 3.3

Restituisce un nuovo oggetto ChainMap dato un numero di maps . Questo oggetto raggruppa più dict o altri mapping per creare un'unica vista aggiornabile.

ChainMap sono utili per gestire i contesti nidificati e gli overlay. Un esempio nel mondo Python si trova nell'implementazione della classe Context nel motore di template di Django. È utile per collegare rapidamente un numero di mappature in modo che il risultato possa essere trattato come una singola unità. Spesso è molto più veloce della creazione di un nuovo dizionario e dell'esecuzione di più chiamate update() .

Ogni volta che uno ha una catena di valori di ricerca, può esserci un caso per ChainMap . Un esempio include avere entrambi i valori specificati dall'utente e un dizionario di valori predefiniti. Un altro esempio sono le mappe dei parametri POST e GET trovate nell'uso del web, ad esempio Django o Flask. Attraverso l'uso di ChainMap si restituisce una vista combinata di due dizionari distinti.

L'elenco dei parametri delle maps è ordinato dalla ricerca per la prima all'ultima ricerca. Le ricerche eseguono la ricerca dei mapping sottostanti fino a quando non viene trovata una chiave. Al contrario, le scritture, gli aggiornamenti e le eliminazioni funzionano solo sulla prima mappatura.

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)

Nota l'impatto dell'ordine su quale valore viene trovato per primo nella ricerca successiva

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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow