range()Python'da aşağıdaki listeyi nasıl üretebilirsiniz ?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
range()Python'da aşağıdaki listeyi nasıl üretebilirsiniz ?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Yanıtlar:
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ı.
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))).
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__?
'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).
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)
range(start, stop, step) - sayıdan başlayın ve her seferinde hareket ederek ulaşılmadığı startsürece sonuç verir . stopstep
Ş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 .
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(bu, önceki değer stop - 1, stopeşit 0).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]
reversed(range(n))
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ı :)
range(1000000000-1,-1,-1)?
timeit range(1000000000-1,-1,-1)komut satırında daha iyi denemeyin , sonuçlarımı görün :-)
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]
-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 .
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)
Ç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:
len()ve tamsayı dizinleri üzerinden[]__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 .
bunun yardımcı olabileceğine inanıyorum,
range(5)[::-1]
aşağıda Kullanımı:
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))daha az hataya açık olduğunu gösteriyor. Saldırı yok Asinox. Sadece dürüst bir gözlem.
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.
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ı.
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.
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))
%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)
%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)
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