Python 3 mengubah rentang ke daftar

178

Saya mencoba membuat daftar dengan angka 1-1000di dalamnya. Jelas ini akan mengganggu menulis / membaca, jadi saya mencoba membuat daftar dengan kisaran di dalamnya. Dalam Python 2 tampaknya:

some_list = range(1,1000)

akan bekerja, tetapi dalam Python 3 jangkauan mirip dengan xrangePython 2?

Adakah yang bisa memberikan wawasan tentang hal ini?

Rumah perahu
sumber
1
juga, some_list[i] == i+1jadi Anda mungkin tidak benar-benar membutuhkan daftar.
njzk2
1
@RikPoggi. misalnya, orang mungkin perlu menyediakan daftar untuk fungsi merencanakan. Kadang-kadang rentang sudah cukup, tetapi rentang tidak dapat digabungkan (tidak dapat diubah), jadi jika Anda perlu menambahkan nilai awal default untuk semua daftar yang diplot, maka perlu diubah menjadi daftar juga.
SherylHohman

Jawaban:

223

Anda bisa membuat daftar dari objek rentang:

my_list = list(range(1, 1001))

Ini adalah bagaimana Anda melakukannya dengan generator di python2.x juga. Secara umum, Anda mungkin tidak memerlukan daftar karena Anda bisa mendapatkan nilai yang my_list[i]lebih efisien ( i + 1), dan jika Anda hanya perlu mengulanginya, Anda bisa langsung kembali range.

Perhatikan juga bahwa pada python2.x, xrangemasih dapat diindeks 1 . Ini berarti bahwa rangepada python3.x juga memiliki properti yang sama 2

1print xrange(30)[12] berfungsi untuk python2.x

2 Pernyataan analog dengan 1 di python3.x adalah print(range(30)[12])dan berfungsi juga.

mgilson
sumber
4
Ini jelas merupakan cara untuk pergi, tetapi sebuah nitpick: ini bukan benar-benar "pemain"
jterrace
@jterrace mengubah "cast" menjadi "convert". Anda benar tentang itu bukan menjadi pemain ... Saya tidak benar-benar tahu harus menyebutnya apa.
mgilson
2
Saya akan mengatakan "membangun" atau "membangun" (atau mungkin "terwujud") - karena Anda tidak "mengubah" (dengan demikian) generator ke daftar, Anda membuat objek daftar baru dari sumber data yang terjadi menjadi generator ... (tapi anggap saja rambut yang membelah dan tidak 100% yakin apa yang saya sukai)
Jon Clements
2
+1 saya untuk "konstruk" karena konsisten dengan bahasa OO lainnya. Ini list(arg)dipahami dalam bahasa lain sebagai memanggil konstruktor listkelas. Sebenarnya, ini juga merupakan kasus Python. Debat apakah objek diisi selama konstruksi (seperti dalam kasus C ++) atau hanya selama metode yang pertama kali disebut secara otomatis (seperti dalam __init__()metode Python ) tidak dapat mengubah ide abstrak dasar. Pandangan saya adalah bahwa konstruktor daftar mengambil iterator dan mengisi daftar dengan nilai yang dikembalikan .
pepr
2
Mengapa ini memberikan kesalahan pada notebook jupyter dan bekerja dengan baik di shell? Kesalahan:'range' object is not callable
subtleseeker
34

Dalam Python <= 3,4 Anda dapat, seperti yang disarankan orang lain, gunakan list(range(10))untuk membuat daftar di luar rentang (Secara umum, semua iterable).

Alternatif lain, diperkenalkan 3.5dengan Python dengan generalisasi yang tidak dibongkar, adalah dengan menggunakan *daftar literal []:

>>> r = range(10)
>>> l = [*r]
>>> print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Meskipun ini setara dengan list(r), itu adalah sintaks literal dan fakta bahwa tidak ada panggilan fungsi yang terlibat membiarkannya mengeksekusi lebih cepat. Ini juga lebih sedikit karakter, jika Anda perlu kode golf :-)

Dimitris Fasarakis Hilliard
sumber
4
Untuk lebih jelasnya, Anda masih dapat membuat satu baris: [*range(10)]berfungsi dengan baik ketika Anda tidak membutuhkannya rangeuntuk tujuan apa pun selain menginisialisasi list. Catatan sisi: Bagian favorit saya (oke, tidak benar-benar) dari generalisasi pembongkaran adalah bahwa sets sekarang kosong memiliki sintaksis literal {*()},, atau seperti saya menyebutnya, operator monyet bermata satu. ;-)
ShadowRanger
@ShadowRanger, itulah awalnya saya berpikir tentang menulisnya. Saya memutuskan untuk menjadi sedikit lebih verbose agar tidak membingungkan pengguna Python baru :-)
Dimitris Fasarakis Hilliard
26

di Python 3.x, range()fungsi mendapat tipenya sendiri. jadi dalam hal ini Anda harus menggunakan iterator

list(range(1000))

nurulhudamustaqim
sumber
11
"dalam hal ini Anda harus menggunakan iterator"? Apa artinya itu artinya?
user2357112 mendukung Monica
2
Saya menggunakan python 3.7 & mencoba x = daftar (rentang (1000)) tetapi mendapat kesalahan TypeError: objek 'daftar' tidak dapat dipanggil
Earthshaker
@Earthshaker Anda harus salah ketik, sepertilist(range(1000))()
wjandrea
17

Alasan mengapa Python3 tidak memiliki fungsi untuk secara langsung mendapatkan daftar berkisar adalah karena desainer Python3 asli cukup pemula di Python2. Dia hanya mempertimbangkan penggunaan range()fungsi dalam for for, oleh karena itu, daftar tidak perlu diperluas. Bahkan, sangat sering kita perlu menggunakan range()fungsi untuk menghasilkan daftar dan beralih ke fungsi.

Oleh karena itu, dalam hal ini, Python3 kurang nyaman dibandingkan dengan Python2 karena:

  • Dalam Python2, kita memiliki xrange()dan range();
  • Dalam Python3, kita punya range()danlist(range())

Meskipun demikian, Anda masih dapat menggunakan ekspansi daftar dengan cara ini:

[*range(N)]
xuancong84
sumber
3
Seluruh titik adalah untuk membuatnya kurang nyaman untuk membuat list, karena itulah biasanya hal yang salah untuk dilakukan. Untuk 99 dari 100 kasus penggunaan, membuat aktual listtidak efisien dan tidak ada gunanya, karena rangeitu sendiri bertindak seperti urutan yang tidak berubah dalam hampir setiap cara, kadang-kadang lebih efisien untuk mem-boot (mis. Tes penahanan untuk ints O(1), vs O(n)untuk lists). Dalam Python 2, orang cenderung menggunakan rangesecara default, meskipun xrangeitu hampir selalu merupakan pilihan yang lebih baik; di Python 3, Anda dapat secara eksplisit memilih untuk masuk list, tidak mendapatkannya secara tidak sengaja dengan menggunakan nama yang salah.
ShadowRanger
7
Komentar tentang desainer Python 3 dan keahliannya dalam Python 2 cukup berani dan kurang ajar.
kazarey
@ Kazarey Tapi apakah itu benar? Ada banyak hal dalam python yang dipertanyakan di sepanjang baris ini
javadba
1
Akan upvote, terutama untuk membongkar-singkatan untuk membangun daftar, tapi saya setuju dengan @kazarey. Komentar tentang desainer tidak berdasar (atau setidaknya, tidak didukung oleh referensi) dan tidak perlu.
Nubarke
12

Anda benar-benar tidak perlu menggunakan angka 1-1000 dalam daftar. Tetapi jika karena alasan tertentu Anda benar-benar membutuhkan angka-angka ini, maka Anda dapat melakukannya:

[i for i in range(1, 1001)]

Singkatnya, Daftar Pemahaman:

Pemahaman daftar di atas diterjemahkan menjadi:

nums = []
for i in range(1, 1001):
    nums.append(i)

Ini hanya sintaksis pemahaman daftar, meskipun dari 2.x. Saya tahu ini akan bekerja di python 3, tetapi saya tidak yakin apakah ada sintaks yang ditingkatkan juga

Rentang mulai termasuk parameter pertama; tetapi berakhir Hingga, Tidak Termasuk Parameter kedua (ketika diberikan 2 parameter; jika parameter pertama dibiarkan, itu akan mulai pada '0')

range(start, end+1)
[start, start+1, .., end]
inspectorG4dget
sumber
20
Mengapa pemahaman? Hanya:list(range(1000))
Rik Poggi
Terima kasih! Maukah Anda menjelaskan mengapa itu untuk saya masuk ... bukan hanya untuk saya masuk?
Boathouse
Saya belum pernah bekerja dengan python3. Jadi saya tidak sepenuhnya yakin tentang cara kerjanya. Saya tahu pemahaman akan bekerja, tetapi tidak 100% di casting. Tetapi jika casting bekerja, maka Anda benar dan cara Anda lebih pythonic.
inspectorG4dget
1
@ inspectorG4dget: Ini bukan "casting", itu memanggil list()konstruktor dengan iterable . The list()konstruktor tahu cara membuat daftar baru ketika diberi objek iterable.
Greg Hewgill
4
@ inspectorG4dget: list(range(1000))akan bekerja di python3 seperti list(xrange(1000))di python2
Rik Poggi
4

Sebenarnya, jika Anda ingin 1-1000 (inklusif), gunakan range(...)fungsi dengan parameter 1 dan 1001:, range(1, 1001)karena range(start, end)fungsinya berubah dari awal hingga (akhir-1), inklusif.

Komputer Kosmik
sumber
0

Gunakan Range di Python 3.

Berikut adalah contoh fungsi yang mengembalikan di antara angka-angka dari dua angka

def get_between_numbers(a, b):
    """
    This function will return in between numbers from two numbers.
    :param a:
    :param b:
    :return:
    """
    x = []
    if b < a:
        x.extend(range(b, a))
        x.append(a)
    else:
        x.extend(range(a, b))
        x.append(b)

    return x

Hasil

print(get_between_numbers(5, 9))
print(get_between_numbers(9, 5))

[5, 6, 7, 8, 9]  
[5, 6, 7, 8, 9]
Rajiv Sharma
sumber
Ini sepertinya menjawab pertanyaan yang berbeda ...?
wjandrea
-1

Sebenarnya, ini adalah retro-gradasi dari Python3 dibandingkan dengan Python2. Tentu saja, Python2 yang menggunakan range () dan xrange () lebih nyaman daripada Python3 yang menggunakan list (range ()) dan range () masing-masing. Alasannya adalah karena perancang asli Python3 tidak terlalu berpengalaman, mereka hanya menganggap penggunaan fungsi rentang oleh banyak pemula untuk beralih pada sejumlah besar elemen di mana memori dan CPU tidak efisien; tetapi mereka mengabaikan penggunaan fungsi rentang untuk menghasilkan daftar nomor. Sekarang, sudah terlambat bagi mereka untuk kembali.

Jika saya menjadi desainer Python3, saya akan:

  1. gunakan irange untuk mengembalikan iterator urutan
  2. gunakan lrange untuk mengembalikan daftar urutan
  3. gunakan rentang untuk mengembalikan urutan iterator (jika jumlah elemen besar, mis. kisaran (9999999) atau daftar urutan (jika jumlah elemen kecil, mis. kisaran (10))

Itu harus optimal.

xuancong84
sumber
Bagaimana ini menjawab pertanyaan?
wjandrea
Ya, itu menjawab pertanyaan dengan meminta pengembang Python3 untuk mengubah dan meningkatkan Python3. Tetapi tidak mungkin mereka akan berubah karena mereka tidak elegan.
xuancong84