Bir listeyi range () ile ters sırada mı yazdırıyorsunuz?


364

range()Python'da aşağıdaki listeyi nasıl üretebilirsiniz ?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

[* Aralık (9, -1, -1)] ne olacak? Süper pitonik!
onofricamila

Yanıtlar:


561

reversed()fonksiyonu kullanın :

reversed(range(10))

Çok daha anlamlı.

Güncelleme:

Bir liste olmasını istiyorsanız (btk'nin işaret ettiği gibi):

list(reversed(range(10)))

Güncelleme:

Yalnızca rangeaynı sonucu elde etmek için kullanmak istiyorsanız, tüm parametrelerini kullanabilirsiniz.range(start, stop, step)

Örneğin, bir liste oluşturmak [5,4,3,2,1,0]için aşağıdakileri kullanabilirsiniz:

range(5, -1, -1)

Daha az sezgisel olabilir, ancak yorumların belirttiği gibi, bu daha verimli ve tersine çevrilmiş liste için aralıkların doğru kullanımı.


13
'Daha az' olmasına rağmen daha az verimlidir. Ve üzerinde dilimleme işlemleri yapamazsınız.
Jakob Bowyer

6
Bu cevap çok açık ve anlaşılması kolay, ama olması gerekiyor range(10), değil range(9). Ayrıca, tam olarak oluşturulmuş bir liste (dilimleme vb. İçin) istiyorsanız, yapmanız gerekir list(reversed(range(10))).
John Y

5
Bu bir yineleyici üretir, OP bir liste şeklinde bir sonuç istedi.
btk

6
Python jeneratörü ile "tersine çevrilmiş" kullanımı (Python 3 serisi yerleşik olarak konuştuğumuzu varsayarak) sadece kavramsal olarak yanlıştır ve yüksek seviyeli dilde programlama yaparken bellek / işlem karmaşıklığını dikkate almamanın yanlış alışkanlıklarını öğretir.
thedk

7
Python3'te, reversedgenel olarak jeneratörleri kabul etmez , ancak kabul eder range. Neden reversed(range(10000))tüm liste için bellek ayırmaya ihtiyaç duyuyorsunuz? ters yineleme sağlayan yöntemi rangeuygulayan bir nesne döndürebilir __reversed__?
avmohan

312

'Range' yerleşik işlevini kullanın. İmza range(start, stop, step). Bu , hariç starttutulan ve stopbu sayıya ulaşıldığında sona eren sayıları veren bir sıra oluşturur stop.

>>> range(9,-1,-1)   
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
    [-2, 0, 2, 4]

Python 3'te bu, rangesalt okunur bir liste gibi etkili bir şekilde işlev gören bir liste dışı nesne üretir (ancak özellikle büyük aralıklar için daha az bellek kullanır).


1
Bunu da açıklayabilir misiniz, ayrıca bana python için herhangi bir web sitesi / pdf kitabı tavsiye edebilir misiniz
ramesh.mimit

8
@ramesh help(range)Bir python kabuğunda çalıştırırsanız , argümanları size söyleyecektir. Bunlar başlayacak sayı, bitecek sayı (özel) ve atılacak adımdır, bu yüzden 9'da başlar ve -1 olana kadar 1 çıkarır (geri dönmeden durur, bu yüzden aralık 0'da biter)
Michael Mrozek

3
@ ramesh.mimit: Sadece resmi Python sitesine gidin. Harika bir eğitim de dahil olmak üzere tam dokümantasyon var.
John Y

5
Gerçekten, bu doğru cevap, ama daha açık bir şekilde açıklanabilir. range(start, stop, step) - sayıdan başlayın ve her seferinde hareket ederek ulaşılmadığı startsürece sonuç verir . stopstep
Bay B

43

Sen kullanabilirsiniz range(10)[::-1]aynı şekilde şeydir range(9, -1, -1)(ortak aşina iseniz ve belki daha okunabilir sequence[::-1]Python deyim).


28

Şimdiye kadar toplanan seçeneklerin "verimliliği" ile ilgilenenler için ...

Jaime RGP cevabı götürdü benim bilgisayarı yeniden başlatın sonra zamanlama nedeniyle biraz "zorlu" bir çözüm Jason anlamıyla (yorum yoluyla) kendi öneri şu. Sizi meraktan mahrum bırakmak için burada sonuçlarımı sunuyorum (en kötüsü):

Jason'ın cevabı (belki de sadece liste kavrayışının gücüne bir gezi ):

$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop

martineau'nun cevabı ( genişletilmiş diller sözdizimine aşina iseniz okunabilir ):

$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop

Michał Šrajer'ın cevabı (kabul edilen, çok okunabilir):

$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop

bene'nin cevabı ( o zaman ilk, ama çok kabataslak ):

$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop

Val Neekman'ınrange(n-1,-1,-1) gösterimini kullanarak son seçeneği hatırlamak kolaydır .


3
Bu cevabı okumadan önce kendi zamanlamalarımı yaptım ve aynı sonuçları aldım.
Todd Owen

13
for i in range(8, 0, -1)

bu sorunu çözecektir. 8'den 1'e çıktı alır ve -1, tersine çevrilmiş bir liste anlamına gelir


10

reverseAralık yöntemi tersine çevrilmiş listeyi döndürebildiğinden kullanımı mantıklı değildir .

N öğe üzerinde yinelemeye sahip olduğunuzda ve geri döndürdüğünüz liste sırasını değiştirmek istediğinizde, onu tanımlayan ve ayarlayan aralıktaki üçüncü parametreyirange(start, stop, step) kullanmanız gerektiğinde , diğer parametreler buna göre ayarlanacaktır:step-1

  1. Sağlamak durdurma olarak parametre -1(bu, önceki değer stop - 1, stopeşit 0).
  2. Başlangıç ​​parametresi kullanımı olarak n-1.

Yani (n) aralığının tersi sırayla eşdeğerliği:

n = 10
print range(n-1,-1,-1) 
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

6
Açıkçası bunu daha az sezgisel buluyorumreversed(range(n))
Nicholas Hamilton

1
@NicholasHamilton Sizinle aynı fikirde, ancak bu cevabın arkasındaki fikir daha az kaynak kullanmaktır ... (ve soru sadece aralık işlevini kullanmaktı :))
Andriy Ivaneyko

Tamam, endişelenme, sanırım duruma bağlı. Örneğin, aralık işlevi bir döngü için dizin olarak kullanılırsa, sınırlı bir etkiye sahip olur, ancak harici bir döngü içinde kullanılırsa, maliyet
Nicholas Hamilton

8

Okunabilirlik bir yana, reversed(range(n))daha hızlı görünüyor 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

Birisi merak ediyor olsaydı :)


bazı numaralara sahip olmak güzel :) - neden siz de eklemediniz range(1000000000-1,-1,-1)?
Kurt

... timeit range(1000000000-1,-1,-1)komut satırında daha iyi denemeyin , sonuçlarımı görün :-)
Wolf

6

Bu sorudaki gereksinim, listazalan sırada 10 büyüklüğünde bir tamsayıları gerektirir. Şimdi python'da bir liste oluşturalım.

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

2
Üçlüyü gerçekten seviyorum. Tutmayı-1 kolaylaştıran tam olarak bu modelwrap one's head around this - Bugün gerçekten verimli olması gerekiyorsa , range(n-1, -1, -1)bir aralığı tersine çevirirken kullanacağını öğrendim .
Kurt

5

Aralık () BIF gibi ters sayıların yazdırılmasını,

for number in range ( 10 , 0 , -1 ) :
    print ( number ) 

Çıktı [10,9,8,7,6,5,4,3,2,1] olacaktır

range () - start'ın dahil olduğu, end'ün münhasır olduğu ve artışın herhangi bir sayı olabileceği ve adım gibi davranabileceği aralık (başlangıç, bitiş, artış / azalma)


5

Çok sık sorulan soru Python 3'ten range(9, -1, -1)daha iyi reversed(range(10))mi? Yineleyicilerle başka dillerde çalışmış olan insanlar hemen tersine çevrilmiş () öğenin tüm değerleri önbelleğe alması ve ardından ters sırada dönmesi gerektiğini düşünürler. Şey, reversed()nesne sadece bir yineleyici ise Python operatörünün çalışmadığıdır. Reversed () işlevinin çalışması için nesnenin aşağıdaki ikisinden birine sahip olması gerekir:

  1. Ya destek len()ve tamsayı dizinleri üzerinden[]
  2. Veya __reversed__()yöntemi uygula.

Yukarıdakilerden hiçbirine sahip olmayan bir nesne üzerinde reversed () işlevini kullanmaya çalışırsanız şunları elde edersiniz:

>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible

Kısacası, Python'lar reversed()sadece nesneler gibi diziler içindir ve bu nedenle ileri yinelemeyle aynı performansa sahip olmalıdır.

Ama ne olacak range()? Bu bir jeneratör değil mi? Python 3'te üretecidir, ancak yukarıdakilerin her ikisini de uygulayan bir sınıfa sarılır. Yanirange(100000) çok fazla bellek kaplamıyor, ancak yine de verimli dizin oluşturma ve geri döndürmeyi destekliyor.

Özet olarak, reversed(range(10))performansta herhangi bir isabet olmadan kullanabilirsiniz .


3

bunun yardımcı olabileceğine inanıyorum,

range(5)[::-1]

aşağıda Kullanımı:

for i in range(5)[::-1]:
    print i 

3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

13
Yanıtınız neden reversed(range(10))daha az hataya açık olduğunu gösteriyor. Saldırı yok Asinox. Sadece dürüst bir gözlem.
Michał Šrajer

Hatalı cevapları ekranda bırakmanın standart olup olmadığını bilmiyorum. Ben ya da birisi düzeltebilir, hatta kaldırabilir miyim?
sinekonata

3
Hayır, hayır sadece onu bırakın ve nasıl 3 upvotes biriktirdiğini merak ediyorum ... Ben moderatör dikkatini ( kırık hariç 18 ay önceki cevap yinelenen) için bayrak olabilir, silip silemezler emin değilim.
OGHaza

Gelecekteki tüm başvurular için: kod yalnızca VLQ değildir ve yanlış yanıtların da işaretlenmesi gerekmez . Oy verin ve devam edin, ancak bu durumda NAA veya mod işaretleme olsun, işaretleme yanlıştır. - Yorumdan
Zoe

2

[:: - 1] olmadan veya ters çevrilmiş -

def reverse(text):
    result = []
    for index in range(len(text)-1,-1,-1):
        c = text[index]
        result.append(c)
    return ''.join(result)

print reverse("python!")

6
Neden birisi bunu yazsın ki "python!"[::-1]?
Daniel

1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

1

Aralık işlevini kullanmanız gerekmez, herhangi bir ek kullanmadan listeyi hızlı bir şekilde ters sırayla döndürmesi gereken listeyi [:: - 1] yapabilirsiniz.


Bu, önceki yanıtta önerilen çözüm gibi görünüyor . Ayrıca, farklı bir önceki yanıta yorum yapmaya çalıştığınız da görünüyor - bunu yapabilmek için biraz daha fazla itibar kazanmanız gerekiyor.
Grisha Levit

1

Bir listeniz olduğunu varsayalım diyelim a = {1,2,3,4,5} Şimdi listeyi ters yazdırmak istiyorsanız, aşağıdaki kodu kullanmanız yeterlidir.

a.reverse
for i in a:
   print(i)

Menzili kullanmayı istediğini biliyorum ama zaten cevaplandı.


0
range(9,-1,-1)
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Doğru formdur. Eğer kullanırsan

reversed(range(10))

0 dava almayacaksın. Örneğin, 10'unuzun sihirli bir sayı olmadığını ve geriye doğru başlamak için kullandığınız bir değişken olduğunu varsayalım. N durumunuz 0 ise, tersine (0 (aralık)) çalışmaz ve bu durumda sıfır dizininde tek bir nesneniz varsa yanlış olur.


0

Birçoğunun (kendim gibi) , sadece bu tür bir geçiş için endeksler üretmek yerine, başlığında belirtildiği gibi, mevcut bir listeyi ters sırayla geçirmenin yaygın bir vakasıyla daha fazla ilgilenebileceğini düşündüm .

Her ne kadar, tüm doğru cevaplar bu dava için hala mükemmel olsa da, Wolf'un cevabında yapılan performans karşılaştırmasının sadece endeks oluşturmak için olduğunu belirtmek istiyorum . Bu yüzden, var olan bir listeyi ters sırada izlemek için benzer bir ölçüt yaptım.

TL; DR a[::-1] en hızlısıdır.

Ön şartlar:

a = list(range(10))

Jason'ın cevabı :

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

martineau'nun cevabı :

%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Michał Šrajer'in cevabı :

%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

bene'nin cevabı :

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

Gördüğünüz gibi, bu durumda açıkça endeksler üretmeye gerek yoktur, bu yüzden en hızlı yöntem daha az ekstra eylem yapan yöntemdir.

Not: Kullanışlı "sihirli komut" olan JupyterLab test ettim %timeit. timeit.timeitKaputun altında standart kullanır . Python 3.7.3 için test edildi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.