
In Python, puoi ordinare un elenco con il metodo sort() o la funzione sorted().
In questo articolo viene assegnato come ordinare un elenco di stringhe numeriche non riempite con zeri.
- ordina() e ordinato()
- Nota sulle stringhe numeriche non riempite con zeri
- Specificare in() o float() per il parametro chiave
- Estrai i numeri nelle stringhe con le espressioni regolari
- Solo un numero in una stringa
- Più di un numero in una stringa
- Alcuni elementi non hanno numero in una stringa
ordina() e ordinato()
sort() è un metodo di una lista, che ordina la lista originale stessa.
l = [10, 1, 5]
l.sort()
print(l)
# [1, 5, 10]
sorted() è una funzione incorporata che crea un nuovo elenco ordinato. L’elenco originale non viene modificato.
l = [10, 1, 5]
print(sorted(l))
# [1, 5, 10]
print(l)
# [10, 1, 5]
Per impostazione predefinita, l’ordinamento viene eseguito in ordine crescente. Se si desidera ordinare in ordine decrescente, impostare il parametro reverse su True. L’esempio usa sorted(), ma puoi anche usare sort().
print(sorted(l, reverse=True))
# [10, 5, 1]
Per ulteriori informazioni, incluso come ordinare tuple e stringhe, vedere l’articolo seguente.
Nota sulle stringhe numeriche non riempite con zeri
Nel caso di un elenco di stringhe numeriche riempite di zeri, viene ordinato senza alcun problema. Si noti che il codice di esempio di seguito utilizza sorted(), ma lo stesso vale per sort().
l = ['10', '01', '05']
print(sorted(l))
# ['01', '05', '10']
Nel caso di un elenco di stringhe numeriche non riempite con zeri, le stringhe vengono ordinate nell’ordine del dizionario, non come numeri. Ad esempio, “10” è considerato minore di “5”.
l = ['10', '1', '5']
print(sorted(l))
# ['1', '10', '5']
Specificare in() o float() per il parametro chiave
sort() e sort() hanno il parametro chiave.
Specificando int() o float(), che converte una stringa ordinata in un numero, per il parametro chiave un elenco di stringhe numeriche viene come numeri, non come stringhe.
Quando una funzione viene specificata come argomento, () non è necessario.
l = ['10', '1', '5']
print(sorted(l, key=int))
# ['1', '5', '10']
print(sorted(l, key=float))
# ['1', '5', '10']
Le stringhe intere possono essere convertite con int() o float(), ma i decimali devono essere convertiti con float().
l = ['10.0', '1.0', '5.0']
print(sorted(l, key=float))
# ['1.0', '5.0', '10.0']
Anche il sort() ha il parametro chiave.
l = ['10', '1', '5']
l.sort(key=int)
print(l)
# ['1', '5', '10']
Come puoi vedere dai risultati, la funzione specificata per chiave viene applicata solo per il confronto e il risultato rimane l’originale.
Se vuoi che risultato sia int o float, ordina l’elenco convertito usando la comprensione dell’elenco.
l = ['10', '1', '5']
print([int(s) for s in l])
# [10, 1, 5]
print(sorted([int(s) for s in l]))
# [1, 5, 10]
Per le stringhe numeriche, devi solo specificare int() o float() come chiave.
Tuttavia, per le stringhe con numeri incorporati, è necessario utilizzare il modulo di regolare re per estrarre la parte numerica della stringa.
l = ['file10.txt', 'file1.txt', 'file5.txt']
Solo un numero in una stringa
Ottieni un oggetto di corrispondenza tramite search() e prendi la parte corrispondente come una stringa con il metodo group().
Usa d+ come modello di espressione regolare. d è un numero, + è una ripetizione di uno o più caratteri e d+ corrisponde a una sequenza di uno o più numeri.
import re
s = 'file5.txt'
print(re.search(r'd+', s).group())
# 5
Questo codice di esempio utilizza una stringa non elaborata.
Poiché viene restituita una stringa, utilizzare int() o float() per convertirla in un numero.
print(type(re.search(r'd+', s).group()))
# <class 'str'>
print(type(int(re.search(r'd+', s).group())))
# <class 'int'>
Con un’espressione lambda, puoi specificare questo processo per il parametro chiave di sort() o sorted().
l = ['file10.txt', 'file1.txt', 'file5.txt']
print(sorted(l))
# ['file1.txt', 'file10.txt', 'file5.txt']
print(sorted(l, key=lambda s: int(re.search(r'd+', s).group())))
# ['file1.txt', 'file5.txt', 'file10.txt']
Se il numero espressione di elementi è piccolo, non devi preoccuparti troppo, ma è più efficiente generare un oggetto di regolare con compile() e utilizzare.
p = re.compile(r'd+')
print(sorted(l, key=lambda s: int(p.search(s).group())))
# ['file1.txt', 'file5.txt', 'file10.txt']
Più di un numero in una stringa
search() restituisce solo la prima corrispondenza.
s = '100file5.txt'
print(re.search(r'd+', s).group())
# 100
findall() restituisce tutte le parti corrispondenti come un elenco.
print(re.findall(r'd+', s))
# ['100', '5']
print(re.findall(r'd+', s)[1])
# 5
Se racchiudi parti di un pattern tra (), puoi estrarre solo quella parte con il metodo groups().
Ad esempio, il modello file(d+) estrae ” da ‘file’. Si noti che richiede una tupla anche se esiste solo una parte corrispondente.
print(re.search(r'file(d+)', s).groups())
# ('5',)
print(re.search(r'file(d+)', s).groups()[0])
# 5
(d+). estratti da..
print(re.search(r'(d+).', s).groups()[0])
# 5
Esempi:
l = ['100file10.txt', '100file1.txt', '100file5.txt']
print(sorted(l, key=lambda s: int(re.findall(r'd+', s)[1])))
# ['100file1.txt', '100file5.txt', '100file10.txt']
print(sorted(l, key=lambda s: int(re.search(r'file(d+)', s).groups()[0])))
# ['100file1.txt', '100file5.txt', '100file10.txt']
print(sorted(l, key=lambda s: int(re.search(r'(d+).', s).groups()[0])))
# ['100file1.txt', '100file5.txt', '100file10.txt']
p = re.compile(r'file(d+)')
print(sorted(l, key=lambda s: int(p.search(s).groups()[0])))
# ['100file1.txt', '100file5.txt', '100file10.txt']
Alcuni elementi non hanno numero in una stringa
Se le stringhe di tutti gli elementi contengono numeri, non c’è problema, ma in caso contrario, considerando il caso di nessuna corrispondenza.
l = ['file10.txt', 'file1.txt', 'file5.txt', 'file.txt']
# print(sorted(l, key=lambda s:int(re.search(r'd+', s).group())))
# AttributeError: 'NoneType' object has no attribute 'group'
Ad esempio, definire la seguente funzione. Il primo parametro è una stringa, il secondo è un oggetto di espressione regolare e il terzo è il valore restituito se non corrisponde.
def extract_num(s, p, ret=0):
search = p.search(s)
if search:
return int(search.groups()[0])
else:
return ret
Il risultato è il seguente. Il modello ha bisogno di () perché usa groups().
p = re.compile(r'(d+)')
print(extract_num('file10.txt', p))
# 10
print(extract_num('file.txt', p))
# 0
print(extract_num('file.txt', p, 100))
# 100
Il terzo argomento è facoltativo.
È possibile specificare questa funzione per il parametro chiave di sort() o sorted().
print(sorted(l, key=lambda s: extract_num(s, p)))
# ['file.txt', 'file1.txt', 'file5.txt', 'file10.txt']
print(sorted(l, key=lambda s: extract_num(s, p, float('inf'))))
# ['file1.txt', 'file5.txt', 'file10.txt', 'file.txt']
Se vuoi mettere elementi che non ordine aumentano i valori numerici alla fine dell’infinito, puoi usare l’infinito inf.
Se una stringa contiene di un numero, basta più l’oggetto dell’espressione regolare.
l = ['100file10.txt', '100file1.txt', '100file5.txt', '100file.txt']
p = re.compile(r'file(d+)')
print(sorted(l, key=lambda s: extract_num(s, p)))
# ['100file.txt', '100file1.txt', '100file5.txt', '100file10.txt']
print(sorted(l, key=lambda s: extract_num(s, p, float('inf'))))
# ['100file1.txt', '100file5.txt', '100file10.txt', '100file.txt']