Cetak daftar dalam urutan terbalik dengan rentang ()?

364

Bagaimana Anda bisa menghasilkan daftar berikut dengan range()Python?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
ramesh.mimit
sumber
Bagaimana dengan [* range (9, -1, -1)]? Super pythonic!
onofricamila

Jawaban:

561

gunakan reversed()fungsi:

reversed(range(10))

Itu jauh lebih bermakna.

Memperbarui:

Jika Anda ingin daftar (seperti yang ditunjukkan btk):

list(reversed(range(10)))

Memperbarui:

Jika Anda hanya ingin menggunakan rangeuntuk mencapai hasil yang sama, Anda dapat menggunakan semua parameternya.range(start, stop, step)

Misalnya, untuk menghasilkan daftar [5,4,3,2,1,0], Anda dapat menggunakan yang berikut ini:

range(5, -1, -1)

Mungkin kurang intuitif tetapi seperti komentar menyebutkan, ini lebih efisien dan penggunaan rentang yang tepat untuk daftar terbalik.

Michał Šrajer
sumber
13
Meskipun kurang efisien. Dan Anda tidak dapat melakukan operasi pemotongan.
Jakob Bowyer
6
Jawaban ini sangat jelas dan mudah dipahami, tetapi harus range(10), tidak range(9). Juga, jika Anda ingin daftar yang lengkap (untuk mengiris, dll.), Anda harus melakukannya list(reversed(range(10))).
John Y
5
Ini menghasilkan iterator, OP meminta hasil dalam bentuk daftar.
btk
6
Menggunakan "terbalik" dengan generator python (dengan asumsi kita berbicara tentang rentang Python 3 built-in) hanya secara konseptual salah dan mengajarkan kebiasaan yang salah tidak mempertimbangkan memori / kompleksitas pemrosesan saat pemrograman dalam bahasa tingkat tinggi.
thedk
7
Dalam Python3, reversedtidak menerima generator secara umum tetapi menerima range. Mengapa reversed(range(10000))perlu mengalokasikan memori untuk seluruh daftar? rangedapat mengembalikan objek yang mengimplementasikan __reversed__metode yang memungkinkan iterasi terbalik yang efisien?
avmohan
312

Gunakan fungsi bawaan 'rentang'. Tanda tangan range(start, stop, step). Ini menghasilkan urutan yang menghasilkan angka, dimulai dengan start, dan berakhir jika stoptelah tercapai, tidak termasuk stop.

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

Dalam Python 3, ini menghasilkan objek non-daftar range, yang berfungsi secara efektif seperti daftar hanya-baca (tetapi menggunakan memori jauh lebih sedikit, terutama untuk rentang besar).

Tuan B
sumber
1
Bisakah Anda jelaskan ini juga, bisakah Anda merekomendasikan saya situs web / buku pdf untuk python
ramesh.mimit
8
@ramesh Jika Anda menjalankan help(range)shell python itu akan memberi tahu Anda argumen. Mereka adalah nomor untuk memulai, nomor untuk mengakhiri (eksklusif), dan langkah yang harus diambil, sehingga mulai dari 9 dan mengurangi 1 hingga menjadi -1 (pada titik itu berhenti tanpa kembali, itulah sebabnya kisaran berakhir pada 0)
Michael Mrozek
3
@ ramesh.mimit: Buka saja situs Python resmi. Ada dokumentasi lengkap di sana, termasuk tutorial yang bagus.
John Y
5
Sungguh, ini adalah jawaban yang tepat, tetapi bisa dijelaskan dengan lebih jelas. range(start, stop, step) - mulai dari angka start, dan hasilkan hasil kecuali stoptelah tercapai, bergerak stepsetiap kali.
Tn. B
43

Anda bisa menggunakan range(10)[::-1]mana hal yang sama range(9, -1, -1)dan bisa dibilang lebih mudah dibaca (jika Anda terbiasa dengan sequence[::-1]idiom Python umum ).

martineau
sumber
28

Bagi mereka yang tertarik dengan "efisiensi" dari opsi yang dikumpulkan sejauh ini ...

Jawaban Jaime RGP membuat saya me-restart komputer saya setelah menghitung waktu solusi Jason yang "menantang" secara harfiah mengikuti saran saya sendiri (melalui komentar). Untuk membuat Anda penasaran tentang downtime, saya sajikan hasil saya (terburuk-pertama):

Jawaban Jason (mungkin hanya perjalanan ke kekuatan pemahaman daftar ):

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

jawaban martineau (dapat dibaca jika Anda terbiasa dengan sintaks irisan diperpanjang ):

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

Jawaban Michał Šrajer (yang diterima, sangat mudah dibaca):

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

jawaban bene (yang paling pertama, tetapi sangat samar saat itu ):

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

Opsi terakhir mudah diingat menggunakan range(n-1,-1,-1)notasi oleh Val Neekman .

Serigala
sumber
3
Saya melakukan timing sendiri sebelum membaca jawaban ini, dan mendapatkan hasil yang sama.
Todd Owen
13
for i in range(8, 0, -1)

akan menyelesaikan masalah ini. Ini akan menampilkan 8 ke 1, dan -1 berarti daftar terbalik

Jutta
sumber
10

Tidak masuk akal untuk digunakan reversekarena metode rentang dapat mengembalikan daftar terbalik.

Ketika Anda memiliki iterasi di atas n item dan ingin mengganti urutan daftar yang dikembalikan oleh range(start, stop, step)Anda harus menggunakan parameter rentang ketiga yang mengidentifikasi stepdan mengaturnya -1, parameter lain harus disesuaikan sesuai:

  1. Berikan parameter berhenti sebagai -1(nilai sebelumnya stop - 1, stopsama dengan 0).
  2. Sebagai parameter mulai digunakan n-1.

Jadi setara dengan rentang (n) dalam urutan terbalik adalah:

n = 10
print range(n-1,-1,-1) 
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Andriy Ivaneyko
sumber
6
Terus terang saya menemukan ini kurang intuitif daripadareversed(range(n))
Nicholas Hamilton
1
@NicholasHamilton Setuju dengan Anda, namun ide di balik jawaban itu adalah dengan menggunakan lebih sedikit sumber daya ... (dan pertanyaannya adalah tentang menggunakan fungsi rentang saja :))
Andriy Ivaneyko
Ok, jangan khawatir, saya kira itu tergantung situasi. Misalnya, Jika fungsi rentang digunakan sebagai indeks untuk loop, maka itu akan memiliki efek terbatas, namun, jika digunakan di dalam loop eksternal, maka biayanya akan bertambah ...
Nicholas Hamilton
8

Di samping kesesuaian, reversed(range(n))tampaknya lebih cepat daripada 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

Hanya jika ada yang bertanya-tanya :)

Jaime RGP
sumber
Senang memiliki beberapa nomor :) - mengapa Anda tidak menambahkan range(1000000000-1,-1,-1)juga?
Wolf
... lebih baik jangan coba timeit range(1000000000-1,-1,-1)di baris perintah, alih-alih lihat hasil saya :-)
Wolf
6

Persyaratan dalam pertanyaan ini membutuhkan listbilangan bulat ukuran 10 dalam urutan menurun. Jadi, mari kita buat daftar dengan 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]
un33k
sumber
2
Saya sangat suka triple.-1 Ini persis pola ini yang membuatnya mudah untuk dipertahankan wrap one's head around this- Hari ini saya belajar bahwa jika itu benar-benar harus efisien , gunakan range(n-1, -1, -1)ketika melintasi rentang dalam urutan terbalik.
Wolf
5

Anda dapat melakukan pencetakan nomor terbalik dengan rentang () Seperti BIF,

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

Output akan [10,9,8,7,6,5,4,3,2,1]

range () - range (start, end, increment / decrement) dimana start inklusif, end eksklusif dan increment dapat berupa angka dan berperilaku seperti langkah

Pak Suryaa Jha
sumber
5

Pertanyaan yang sangat sering ditanyakan adalah apakah range(9, -1, -1)lebih baik daripada reversed(range(10))di Python 3? Orang-orang yang telah bekerja dalam bahasa lain dengan iterator segera cenderung berpikir bahwa terbalik () harus men-cache semua nilai dan kemudian kembali dalam urutan terbalik. Masalahnya adalah bahwa reversed()operator Python tidak bekerja jika objek itu hanya sebuah iterator. Objek harus memiliki satu dari dua di bawah ini agar terbalik () berfungsi:

  1. Baik dukungan len()dan indeks integer via[]
  2. Atau apakah __reversed__()metode telah diterapkan.

Jika Anda mencoba menggunakan reversed () pada objek yang tidak memiliki di atas maka Anda akan mendapatkan:

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

Jadi singkatnya, Python reversed()hanya dimaksudkan pada array seperti objek dan karenanya harus memiliki kinerja yang sama dengan iterasi maju.

Tapi bagaimana dengan itu range()? Bukankah itu generator? Dalam Python 3 itu adalah generator tetapi dibungkus dalam kelas yang mengimplementasikan kedua hal di atas. Begiturange(100000) tidak memakan banyak memori tetapi masih mendukung pengindeksan dan pembalikan yang efisien.

Jadi secara ringkas, Anda dapat menggunakan reversed(range(10))tanpa hit pada kinerja.

Shital Shah
sumber
3

Saya percaya ini bisa membantu,

range(5)[::-1]

di bawah ini adalah Penggunaan:

for i in range(5)[::-1]:
    print i 
dineshsprabu
sumber
3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Asinox
sumber
13
Jawaban Anda menunjukkan mengapa reversed(range(10))rawan kesalahan. Jangan tersinggung Asinox. Pengamatan yang jujur ​​saja.
Michał Šrajer
Saya tidak tahu apakah standar untuk membiarkan jawaban yang salah ditampilkan. Dapatkah saya atau seseorang memperbaikinya atau bahkan menghapusnya?
sinekonata
3
@ sinus, jangan tinggalkan dan bertanya-tanya bagaimana akumulasi 3 upvotes ... Saya kira Anda bisa menandai itu untuk perhatian moderator (duplikat jawaban dari 18 bulan sebelumnya kecuali rusak), tidak yakin apakah mereka akan menghapusnya atau tidak.
OGHaza
Untuk semua referensi di masa mendatang: kode saja bukan VLQ , dan jawaban yang salah tidak seharusnya ditandai juga . Turunkan suara dan lanjutkan, tetapi penandaan salah dalam hal ini, apakah NAA atau penandaan mod. - Dari ulasan
Zoe
2

Menggunakan tanpa [:: - 1] atau terbalik -

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!")
rhel.user
sumber
6
Mengapa seseorang harus menulis ini "python!"[::-1]?
Daniel
1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jason
sumber
1

Anda tidak perlu menggunakan fungsi rentang, Anda cukup melakukan daftar [:: - 1] yang akan mengembalikan daftar dalam urutan terbalik dengan cepat, tanpa menggunakan tambahan apa pun.

pengguna7420740
sumber
Tampaknya ini adalah solusi yang disarankan dalam jawaban sebelumnya . Tampaknya Anda mungkin mencoba mengomentari jawaban sebelumnya yang berbeda - Anda harus mendapatkan sedikit lebih banyak reputasi sebelum dapat melakukannya.
Grisha Levit
1

Misalkan Anda memiliki daftar, panggil a = {1,2,3,4,5} Sekarang jika Anda ingin mencetak daftar secara terbalik maka cukup gunakan kode berikut.

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

Saya tahu Anda bertanya menggunakan rentang tetapi sudah dijawab.

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

Apakah bentuk yang benar. Jika Anda menggunakan

reversed(range(10))

Anda tidak akan mendapatkan 0 kasing. Sebagai contoh, katakan 10 Anda bukan angka ajaib dan variabel yang Anda gunakan untuk mencari mulai dari terbalik. Jika case n Anda adalah 0, terbalik (rentang (0)) tidak akan mengeksekusi yang salah jika Anda kebetulan memiliki satu objek di indeks nol.

pengguna3807372
sumber
0

Saya berpikir bahwa banyak (seperti saya) bisa lebih tertarik pada kasus umum melintasi daftar yang ada dalam urutan terbalik , seperti yang dinyatakan dalam judul, daripada hanya membuat indeks untuk traversal tersebut.

Meskipun, semua jawaban yang benar masih baik-baik saja untuk kasus ini, saya ingin menunjukkan bahwa perbandingan kinerja yang dilakukan dalam jawaban Wolf adalah untuk menghasilkan indeks saja. Jadi saya telah membuat tolok ukur yang sama untuk melintasi daftar yang ada dalam urutan terbalik.

TL; DR a[::-1] adalah yang tercepat.

Prasyarat:

a = list(range(10))

Jawaban Jason :

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

jawaban martineau :

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

Jawaban Michał Šrajer :

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

jawaban bene :

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

Seperti yang Anda lihat, dalam hal ini tidak perlu secara eksplisit menghasilkan indeks, jadi metode tercepat adalah yang membuat tindakan lebih sedikit.

NB: Saya diuji di JupyterLab yang memiliki "perintah ajaib" yang praktis %timeit. Menggunakan standar di timeit.timeitbawah tenda. Diuji untuk Python 3.7.3

pkuderov
sumber