2015-05-02 8 views
6

Per incrementare un singolo articolo in collections.Counter, devi aggiungerlo a un elenco per utilizzare Counter.update.Classe counter Python: aggiungi o incrementa singolo elemento

c = Counter() 

for item in something: 
    for property in properties_of_interest: 
     if item.has_some_property: # pseudocode: more complex logic here 
      c.update([item.property]) 
     elif item.has_some_other_property: 
      c.update([item.other_property]) 
     # elif... etc 

Un set utilizza .update per aggiungere più elementi, e add di aggiungere una sola. Perché lo Counter non funziona allo stesso modo? Posso farlo agire in modo simile (ad esempio, eliminare la necessità di inserire la proprietà in una lista)?

Immagina un caso in cui hai alcuni oggetti sconosciuti, e stai provando molte cose diverse rapidamente per scoprire alcune cose preliminari su di loro: prestazioni e ridimensionamento non contano, e una comprensione farebbe aggiungere e sottrarre tempo logico -consuming.

+0

Quindi, che cosa c'è di sbagliato nel codice e in "Counter.update"? – Kasramvd

+0

Devo incollarlo su una lista finta. Non è un grosso problema; Mi sto solo chiedendo se non ci sia un pensiero dietro a 'add'. – bahmait

+0

Il metodo 'update' accetta un argomento aas iterabile e si presume che l'iterabile sia una sequenza di elementi, non una sequenza di coppie (chiave, valore). – Kasramvd

risposta

7

Beh, non si ha realmente bisogno di utilizzare metodi di Counter per contare, vero? C'è un operatore += per questo, che funziona anche in combinazione con Counter.

c = Counter() 
for item in something: 
    if item.has_some_property: 
     c[item.property] += 1 
    elif item.has_some_other_property: 
     c[item.other_property] += 1 
    elif item.has_some.third_property: 
     c[item.third_property] += 1 
3

C'è un modo più Pythonic di fare ciò che si vuole:

c = Counter(item.property for item in something if item.has_some_property) 

utilizza una generator expression anziché aperto codifica del ciclo.

Modifica: Mancato il paragrafo di mancata elencazione. Continuo a pensare che questo sia il modo di utilizzare effettivamente lo standard Counter. Se hai troppo codice da inserire nell'espressione di un generatore o nella comprensione di una lista, spesso è meglio inserirlo in una funzione e chiamarla da una comprensione.

+0

Una comprensione di lista, un'espressione di generatore - può farlo, ma con if/elif/elif/etc complessi, non funziona. – bahmait

+0

@bahmait e come immaginate che 'set.add' aiuti con complessi' if/elif/elif' ecc ...? –

+0

@bahmait: appena modificato. Immaginare quella logica in una funzione separata è il modo Pythonico per farlo, immagino. Sono d'accordo che un metodo '' add() '' potrebbe essere una bella aggiunta, ma forse l'omissione è stata deliberata per spingere le persone allo stile del generatore. –

3
>>> c = collections.Counter(a=23, b=-9) 

È possibile aggiungere un nuovo elemento e impostare il suo valore in questo modo:

>>> c['d'] = 8 
>>> c 
Counter({'a': 23, 'd': 8, 'b': -9}) 

Incremento:

>>> c['d'] += 1 
>>> c 
Counter({'a': 23, 'd': 9, 'b': -9} 

Nota però che c['b'] = 0 non elimina:

>>> c['b'] = 0 
>>> c 
Counter({'a': 23, 'd': 9, 'b': 0}) 

Per cancellare E Utilizzare del:

>>> del c['b'] 
>>> c 
Counter({'a': 23, 'd': 9}) 

Counter è una sottoclasse dict

+1

In realtà non si sta 'aggiungendo', si sta 'impostando' '' 'd''' per contare = 8. Devi usare '' c ['d'] = c.get ('d', 0) + 1'' per far funzionare il conteggio. –

+2

@ChristianAichinger, buon punto. btw, 'c ['d'] + = 1' funziona. – shx2

+0

Questa era la pausa nel caso. Ringrazia tutti. – bahmait