2015-08-10 19 views
12

Ho un programma che restituisce un set di domini con ranghi in questo modo:Come convertire i valori del dizionario in int in Python?

ranks = [ 
    {'url': 'example.com', 'rank': '11,279'}, 
    {'url': 'facebook.com', 'rank': '2'}, 
    {'url': 'google.com', 'rank': '1'} 
] 

sto cercando di ordinarli salendo rango con sorted:

results = sorted(ranks,key=itemgetter("rank")) 

Tuttavia, dal momento che i valori di "rango" sono stringhe, allora li ordina alfanumericamente invece che per valore crescente:

1. google.com: 1 

2. example.com: 11,279 

3. facebook.com: 2 

ho bisogno di convertire i valori del solo la chiave "rank" per i numeri interi in modo che vengano ordinati correttamente. Qualche idea?

+2

Se è possibile creare il dizionario da soli, preferire numeri interi anziché stringhe. – wenzul

risposta

19

Sei quasi arrivato. È necessario convertire i valori scelti per interi dopo la sostituzione ,, come questo

results = sorted(ranks, key=lambda x: int(x["rank"].replace(",", ""))) 

Per esempio,

>>> ranks = [ 
...  {'url': 'example.com', 'rank': '11,279'}, 
...  {'url': 'facebook.com', 'rank': '2'}, 
...  {'url': 'google.com', 'rank': '1'} 
... ] 
>>> from pprint import pprint 
>>> pprint(sorted(ranks, key=lambda x: int(x["rank"].replace(",", "")))) 
[{'rank': '1', 'url': 'google.com'}, 
{'rank': '2', 'url': 'facebook.com'}, 
{'rank': '11,279', 'url': 'example.com'}] 

Nota: ho appena usato pprint funzione per stampare piuttosto il risultato.

Qui, x sarà l'oggetto corrente per cui viene determinato il valore key. Otteniamo il valore dell'attributo rank da esso, sostituiamo , con una stringa vuota e quindi lo abbiamo convertito in un numero con int.


Se non si desidera sostituire , e gestire in modo corretto, quindi è possibile utilizzare locale module's atoi function, come questo

>>> import locale 
>>> pprint(sorted(ranks, key=lambda x: int(locale.atoi(x["rank"])))) 
[{'rank': '1', 'url': 'google.com'}, 
{'rank': '2', 'url': 'facebook.com'}, 
{'rank': '11,279', 'url': 'example.com'}] 
+0

Ho una domanda aggiuntiva: dato che l'OP sta chiedendo in realtà di convertire i valori in 'int' solo in modo da poterli ordinare correttamente, il suo problema è con l'ordinamento credo, e non con il tipo.Non è possibile ordinare i valori dopo aver sostituito ',' e aspettarsi lo stesso risultato, senza gettarli negli int che? – tomasyany

+4

@tomasyany: sì, ma quella specie sarebbe lessicografica, non numerica e ''11 '<' 9'' anche se' 11> 9'. – DSM

+0

Usando 'locale.atoi' come sopra, ottengo' ValueError: letterale non valido per int() con base 10: '11, 279'' –

1
x=[{'url': 'example.com', 'rank': '11,279'}, {'url': 'facebook.com', 'rank': '2'}, {'url': 'google.com', 'rank': '1'},{'url': 'google.com', 'rank': '11,280'},{'url': 'google.com', 'rank': '12'}] 

results = sorted(x,key=lambda k:ast.literal_eval(k.get("rank").replace(",",""))) 
print [i for i in results] 

che si dovrebbe usare ast.literal.eval e quindi confrontare per la precisione e preciso

uscita: [{'url': 'google.com', 'rank': '1'}, {'url': 'facebook.com', 'rank': '2'}, {'url': 'example.com', 'rank': '11,279'}, {'url': 'google.com', 'rank': '11,280'}, {'url': 'google.com', 'rank': '12'}]

+0

Questo non gira 11279 in 11.279 So che l'uso di punto e virgola all'interno di numeri differisce da paese a paese e questo potrebbe essere un problema –

+0

@ RolfofSaxony sì sì !!!! modificato! grazie :) – vks

3

Voglio solo far notare che la struttura dei dati potrebbe potenzialmente essere migliorata qui. Hai una lista di mini-dizionari ma sembra che tu possa avere un singolo dizionario dato che "rank" e "url" sono impliciti. Utilizza ciascun url univoco come chiave e ogni rango dell'URL come valore o conteggio, in modo da sfruttare meglio le capacità del dizionario IMHO. Se hai trovato la struttura di dati corrente come uscita da qualche altra parte, si può facilmente comprimere in un dizionario contatore più efficiente con la conversione a intero ranghi come valori utilizzando la funzione dict():

>>> ranks 
[{'url': 'example.com', 'rank': '11,279'}, {'url': 'facebook.com', 'rank': '2'}, {'url': 'google.com', 'rank': '1'}] 
>>> compressed = dict([(x['url'], int(x['rank'].replace(',', ''))) for x in ranks]) 
>>> compressed 
{'facebook.com': 2, 'google.com': 1, 'example.com': 11279} 

Se si sta andando per avere molti dati questo sarà più compatto ed è più intuitivo lavorare con. È possibile utilizzare questo facilmente per cose come belle stampe basate su ranghi:

>>> print ''.join(['{k:>12}: {v:,}\n'.format(k=item[0], v=item[1]) for item in sorted(compressed.items(), key=lambda i: i[1])]) 
    google.com: 1 
facebook.com: 2 
example.com: 11,279 
Problemi correlati