Come puoi produrre il seguente elenco con range()in Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Come puoi produrre il seguente elenco con range()in Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Risposte:
utilizzare la reversed()funzione:
reversed(range(10))
È molto più significativo.
Aggiornare:
Se vuoi che sia un elenco (come sottolineato da BTK):
list(reversed(range(10)))
Aggiornare:
Se si desidera utilizzare solo rangeper ottenere lo stesso risultato, è possibile utilizzare tutti i suoi parametri.range(start, stop, step)
Ad esempio, per generare un elenco [5,4,3,2,1,0], è possibile utilizzare quanto segue:
range(5, -1, -1)
Potrebbe essere meno intuitivo, ma come menzionano i commenti, questo è più efficiente e il corretto utilizzo dell'intervallo per l'elenco invertito.
range(10)no range(9). Inoltre, se si desidera un elenco completo (per tagliare, ecc.), È necessario farlo list(reversed(range(10))).
reversednon accetta generatori in generale ma accetta range. Perché dovrebbe essere reversed(range(10000))necessario allocare memoria per l'intero elenco? rangepuò restituire un oggetto che implementa il __reversed__metodo che consente un'iterazione inversa efficiente?
Utilizzare la funzione integrata 'range'. La firma è range(start, stop, step). Questo produce una sequenza che produce numeri, iniziando con starte terminando se stopè stata raggiunta, escluso stop.
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
[-2, 0, 2, 4]
In Python 3, questo produce un rangeoggetto non-list , che funziona efficacemente come un elenco di sola lettura (ma usa molta meno memoria, in particolare per intervalli di grandi dimensioni).
help(range)in una shell Python ti dirà gli argomenti. Sono il numero su cui iniziare, il numero su cui terminare (esclusivo) e il passo da compiere, quindi inizia da 9 e sottrae 1 fino a raggiungere -1 (a quel punto si ferma senza ritornare, motivo per cui l'intervallo termina a 0)
range(start, stop, step) - iniziare dal numero starte produrre risultati se non stopè stato raggiunto, spostandosi di stepvolta in volta.
Per coloro che sono interessati all '"efficienza" delle opzioni finora raccolte ...
La risposta di Jaime RGP mi ha portato a riavviare il computer dopo temporizzazione la soluzione un po ' "sfida" di Jason letteralmente seguito il mio suggerimento (via commento). Per risparmiare ai tuoi curiosi i tempi di fermo, ti presento i miei risultati (il peggiore per primi):
La risposta di Jason (forse solo un'escursione nel potere della comprensione della lista ):
$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop
La risposta di martineau (leggibile se si ha familiarità con la sintassi delle sezioni estese ):
$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop
La risposta di Michał Šrajer (quella accettata, molto leggibile):
$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop
la risposta di Bene (la prima, ma molto approssimativa in quel momento ):
$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop
L'ultima opzione è facile da ricordare usando la range(n-1,-1,-1)notazione di Val Neekman .
reverseperché il metodo range può restituire un elenco invertito.Quando si ha iterazione su n elementi e si desidera sostituire l'ordine dell'elenco restituito, range(start, stop, step)è necessario utilizzare il terzo parametro dell'intervallo che lo identifica stepe impostarlo su -1, altri parametri devono essere adeguati di conseguenza:
-1(il valore precedente di stop - 1, stopera uguale a 0).n-1.Quindi l'equivalente dell'intervallo (n) in ordine inverso sarebbe:
n = 10
print range(n-1,-1,-1)
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(n))
Leggibilità a parte, reversed(range(n))sembra essere più veloce di range(n)[::-1].
$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop
Solo se qualcuno si chiedeva :)
range(1000000000-1,-1,-1)?
timeit range(1000000000-1,-1,-1)dalla riga di comando, invece vedi i miei risultati :-)
Il requisito in questa domanda richiede un numero listintero di dimensione 10 in ordine decrescente. Quindi, produciamo un elenco in Python.
# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------
# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>
# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
-1 È esattamente questo modello che lo rende facile da mantenere wrap one's head around this- Oggi ho imparato che se deve davvero essere efficiente , utilizzare range(n-1, -1, -1)quando si percorre una gamma in ordine inverso.
Puoi eseguire la stampa di numeri inversi con range () BIF Come,
for number in range ( 10 , 0 , -1 ) :
print ( number )
L'output sarà [10,9,8,7,6,5,4,3,2,1]
range () - range (inizio, fine, incremento / decremento) dove inizio è inclusivo, fine è esclusiva e l'incremento può essere qualsiasi numero e si comporta come un passo
Molto spesso la domanda è se sia range(9, -1, -1)meglio che reversed(range(10))in Python 3? Le persone che hanno lavorato in altre lingue con iteratori tendono immediatamente a pensare che reversed () debba memorizzare nella cache tutti i valori e quindi tornare in ordine inverso. Il fatto è che l' reversed()operatore di Python non funziona se l'oggetto è solo un iteratore. L'oggetto deve avere uno dei due seguenti per reverse () per funzionare:
len()e indici interi tramite[]__reversed__()implementato il metodo.Se provi a usare reverse () su un oggetto che non ha nessuno dei precedenti, otterrai:
>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible
Quindi, in breve, Python reversed()si intende solo su array come oggetti e quindi dovrebbe avere le stesse prestazioni dell'iterazione diretta.
Ma che dire range()? Non è un generatore? In Python 3 è un generatore ma racchiuso in una classe che implementa entrambi i precedenti. Quindi range(100000)non occupa molta memoria ma supporta comunque l'indicizzazione e l'inversione efficienti.
Quindi, in sintesi, è possibile utilizzare reversed(range(10))senza alcun impatto sulle prestazioni.
credo che questo possa aiutare,
range(5)[::-1]
sotto è l'uso:
for i in range(5)[::-1]:
print i
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(10))è meno soggetta a errori. Senza offesa Asinox. Solo un'osservazione onesta.
Non devi necessariamente usare la funzione range, puoi semplicemente fare list [:: - 1] che dovrebbe riportare rapidamente la lista in ordine inverso, senza usare alcuna aggiunta.
Supponi di avere un elenco chiamalo a = {1,2,3,4,5} Ora se vuoi stampare l'elenco al contrario, usa semplicemente il seguente codice.
a.reverse
for i in a:
print(i)
So che hai chiesto di usare range ma ha già risposto.
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
È la forma corretta. Se usi
reversed(range(10))
non otterrai un caso 0. Ad esempio, supponi che il tuo 10 non sia un numero magico e una variabile che stai utilizzando per la ricerca inizi dal retro. Se il tuo n caso è 0, inverso (range (0)) non verrà eseguito, il che è sbagliato se per caso hai un singolo oggetto nell'indice zero.
Ho pensato che molti (come me stesso) potrebbero essere più interessati a un caso comune di attraversamento di un elenco esistente in ordine inverso, invece, come indicato nel titolo, piuttosto che generare semplicemente indici per tale attraversamento.
Anche se, tutte le risposte giuste sono ancora perfettamente valide per questo caso, voglio sottolineare che il confronto delle prestazioni fatto nella risposta di Wolf è solo per la generazione di indici. Quindi ho fatto benchmark simili per attraversare un elenco esistente in ordine inverso.
TL; DR a[::-1] è il più veloce.
Prerequisiti:
a = list(range(10))
%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
La risposta di Michał Šrajer :
%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Come vedi, in questo caso non è necessario generare esplicitamente indici, quindi il metodo più veloce è quello che fa meno azioni extra.
NB: ho provato su JupyterLab che ha un pratico "comando magico" %timeit. Utilizza standard timeit.timeitsotto il cofano. Testato per Python 3.7.3