Anda jelas meminta jumlah elemen dalam daftar. Jika seorang pencari datang ke sini mencari ukuran objek dalam memori, ini adalah pertanyaan & jawaban aktual yang mereka cari: Bagaimana cara menentukan ukuran objek dalam Python?
Aaron Hall
Jawaban:
2640
The len()fungsi dapat digunakan dengan beberapa jenis yang berbeda dengan Python - baik built-in tipe dan jenis perpustakaan. Sebagai contoh:
>>> len([1,2,3])3
Dokumentasi 2.x resmi ada di sini:
Dokumentasi resmi 3.x ada di sini:len() len()
Segala sesuatu di Python adalah objek, termasuk daftar. Semua objek memiliki semacam header dalam implementasi C.
Daftar dan objek builtin serupa lainnya dengan "ukuran" di Python, khususnya, memiliki atribut yang disebut ob_size, di mana jumlah elemen dalam objek di-cache. Jadi memeriksa jumlah objek dalam daftar sangat cepat.
Mengembalikan panjang (jumlah item) suatu objek. Argumennya bisa berupa urutan (seperti string, byte, tuple, daftar, atau rentang) atau koleksi (seperti kamus, set, atau set beku).
lendiimplementasikan dengan __len__, dari dokumen model data :
object.__len__(self)
Dipanggil untuk mengimplementasikan fungsi bawaan len(). Harus mengembalikan panjang objek, bilangan bulat> = 0. Juga, objek yang tidak mendefinisikan metode __nonzero__()[dengan Python 2 atau __bool__()Python 3] dan __len__()metode yang mengembalikan nol dianggap salah dalam konteks Boolean.
Dan kita juga bisa melihat itu __len__adalah metode daftar:
items.__len__()
mengembalikan 3.
Jenis builtin Anda bisa mendapatkan len(panjang) dari
Dan sebenarnya kita melihat kita bisa mendapatkan informasi ini untuk semua jenis yang dijelaskan:
Walaupun ini mungkin tidak berguna karena fakta bahwa itu akan jauh lebih masuk akal sebagai fungsi "di luar kotak", peretasan yang cukup sederhana adalah membangun kelas dengan lengthproperti:
class slist(list):@propertydef length(self):return len(self)
Anda dapat menggunakannya seperti ini:
>>> l = slist(range(10))>>> l.length
10>>>print l
[0,1,2,3,4,5,6,7,8,9]
Pada dasarnya, ini persis identik dengan objek daftar, dengan manfaat tambahan dari memiliki lengthproperti ramah-OOP .
Seperti biasa, jarak tempuh Anda mungkin bervariasi.
asal Anda tahu, Anda bisa melakukan length = property(len)dan melewatkan fungsi pembungkus satu baris dan menyimpan dokumentasi / introspeksi lendengan properti Anda.
Tadhg McDonald-Jensen
17
Selain itu lenAnda juga dapat menggunakan operator.length_hint(membutuhkan Python 3.4+). Untuk yang normal listkeduanya sama, tetapi length_hintmemungkinkan untuk mendapatkan panjang daftar-iterator, yang bisa berguna dalam keadaan tertentu:
>>>from operator import length_hint
>>> l =["apple","orange","banana"]>>> len(l)3>>> length_hint(l)3>>> list_iterator = iter(l)>>> len(list_iterator)TypeError: object of type 'list_iterator' has no len()>>> length_hint(list_iterator)3
Tapi length_hintmenurut definisi hanya "petunjuk", jadi sebagian besar waktu lenlebih baik.
Saya telah melihat beberapa jawaban yang menyarankan mengakses __len__. Ini baik-baik saja ketika berhadapan dengan kelas bawaan seperti list, tetapi bisa menimbulkan masalah dengan kelas khusus, karena len(dan length_hint) menerapkan beberapa pemeriksaan keamanan. Misalnya, keduanya tidak memungkinkan panjang negatif atau panjang yang melebihi nilai tertentu ( sys.maxsizenilai). Jadi selalu lebih aman menggunakan lenfungsi daripada __len__metode!
Dalam Python, nama yang dimulai dengan garis bawah adalah metode non-publik semantik dan tidak boleh digunakan oleh pengguna.
Aaron Hall
2
1 __foo__.: ini hanya sebuah konvensi, cara bagi sistem Python untuk menggunakan nama yang tidak akan bertentangan dengan nama pengguna. 2 _foo.: ini hanya sebuah konvensi, cara bagi pemrogram untuk menunjukkan bahwa variabel bersifat pribadi (apa pun artinya dengan Python). 3 __foo.: ini memiliki arti nyata: penerjemah menggantikan nama ini dengan _classname__foocara untuk memastikan bahwa nama tersebut tidak akan tumpang tindih dengan nama yang serupa di kelas lain. * Tidak ada bentuk garis bawah yang memiliki makna di dunia Python. * Tidak ada perbedaan antara kelas, variabel, global, dll dalam konvensi ini.
Shai Alon
4
T&J ini menjelaskan mengapa Anda tidak boleh menggunakan metode khusus secara langsung sebagai pengguna: stackoverflow.com/q/40272161/541136
Aaron Hall
@ AaronHall tapi untuk fungsi len hampir sama. Mungkin lebih cepat untuk variabel yang sangat besar. Namun, saya mengerti maksud Anda dan kami harus menggunakan len (obj) dan bukan obj .__ len __ ().
Shai Alon
7
Dan untuk kelengkapan (terutama pendidikan), dimungkinkan tanpa menggunakan len()fungsi. Saya tidak akan memaafkan ini sebagai opsi yang baik JANGAN PROGRAM SEPERTI INI DI PYTHON , tetapi ini melayani tujuan untuk mempelajari algoritma.
(Usus besar dalam list[:]adalah implisit dan karena itu juga opsional.)
Pelajaran di sini untuk programmer baru adalah: Anda tidak bisa mendapatkan jumlah item dalam daftar tanpa menghitungnya di beberapa titik. Pertanyaannya menjadi: kapan waktu yang tepat untuk menghitungnya? Misalnya, kode berperforma tinggi seperti sambungkan sistem panggilan untuk soket (ditulis dalam C) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, tidak menghitung panjang elemen (memberikan tanggung jawab itu pada kode panggilan). Perhatikan bahwa panjang alamat dilewatkan untuk menyimpan langkah penghitungan panjang terlebih dahulu? Pilihan lain: secara komputasi, mungkin masuk akal untuk melacak jumlah item saat Anda menambahkannya dalam objek yang Anda lewati. Pikiran bahwa ini membutuhkan lebih banyak ruang dalam memori. Lihat jawaban Naftuli Kay .
Contoh melacak panjang untuk meningkatkan kinerja sambil mengambil lebih banyak ruang di memori. Perhatikan bahwa saya tidak pernah menggunakan fungsi len () karena panjangnya dilacak:
classMyList(object):def __init__(self):
self._data =[]
self.length =0# length tracker that takes up memory but makes length op O(1) time# the implicit iterator in a list classdef __iter__(self):for elem in self._data:yield elem
def add(self, elem):
self._data.append(elem)
self.length +=1def remove(self, elem):
self._data.remove(elem)
self.length -=1
mylist =MyList()
mylist.add(1)
mylist.add(2)
mylist.add(3)print(mylist.length)# 3
mylist.remove(3)print(mylist.length)# 2
Mengapa for item in list[:]:? Mengapa tidak for item in list:? Juga, saya gunakan += 1untuk menambah.
Nenek Mencapai
@GrannyAching Saya secara eksplisit menyebutkan titik dua opsional (range specifier). Saya meninggalkan range specifier di sana untuk tujuan pendidikan - ada baiknya mengetahui bahwa itu tersirat. Tipe daftar [] juga disimpulkan, seperti yang Anda sarankan-setara dengan kode saya. Operator kenaikan juga setara dengan menambahkan 1 ke variabel yang ada, namun lebih pendek dalam semua kasus. Jadi saya setuju bahwa itu harus digunakan jika itu alasan Anda. Kode ini seharusnya tidak dimasukkan ke dalam produksi di mana saja, kecuali (kecuali ketika belajar pemrograman).
Jonathan Komar
0
Dalam hal bagaimana len()sebenarnya bekerja, ini adalah implementasi C-nya :
static PyObject*
builtin_len(PyObject*module,PyObject*obj)/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/{Py_ssize_t res;
res =PyObject_Size(obj);if(res <0){assert(PyErr_Occurred());return NULL;}returnPyLong_FromSsize_t(res);}
Py_ssize_tadalah panjang maksimum yang dapat dimiliki objek. PyObject_Size()adalah fungsi yang mengembalikan ukuran suatu objek. Jika tidak dapat menentukan ukuran suatu objek, ia mengembalikan -1. Dalam hal ini, blok kode ini akan dieksekusi:
if(res <0){assert(PyErr_Occurred());return NULL;}
Dan sebagai hasilnya muncul pengecualian. Jika tidak, blok kode ini akan dieksekusi:
returnPyLong_FromSsize_t(res);
resyang merupakan Cbilangan bulat, diubah menjadi python longdan dikembalikan. Semua bilangan bulat python disimpan seperti longssejak Python 3.
Mengapa mengetahui, atau mengetahui tentang masalah implementasi C?
cs95
Karena pertanyaan ini tidak spesifik untuk CPython, jawaban ini mungkin menyesatkan. PyPy, IronPython, ... dapat dan mengimplementasikannya secara berbeda.
Jawaban:
The
len()
fungsi dapat digunakan dengan beberapa jenis yang berbeda dengan Python - baik built-in tipe dan jenis perpustakaan. Sebagai contoh:Dokumentasi 2.x resmi ada di sini: Dokumentasi resmi 3.x ada di sini:
len()
len()
sumber
Untuk menemukan ukuran daftar, menggunakan fungsi builtin,
len
:Dan sekarang:
mengembalikan 3.
Penjelasan
Segala sesuatu di Python adalah objek, termasuk daftar. Semua objek memiliki semacam header dalam implementasi C.
Daftar dan objek builtin serupa lainnya dengan "ukuran" di Python, khususnya, memiliki atribut yang disebut
ob_size
, di mana jumlah elemen dalam objek di-cache. Jadi memeriksa jumlah objek dalam daftar sangat cepat.Tetapi jika Anda memeriksa apakah ukuran daftar nol atau tidak, jangan gunakan
len
- sebagai gantinya, masukkan daftar dalam konteks boolean - itu diperlakukan sebagai False jika kosong, Benar sebaliknya .Dari dokumen
len(s)
len
diimplementasikan dengan__len__
, dari dokumen model data :object.__len__(self)
Dan kita juga bisa melihat itu
__len__
adalah metode daftar:mengembalikan 3.
Jenis builtin Anda bisa mendapatkan
len
(panjang) dariDan sebenarnya kita melihat kita bisa mendapatkan informasi ini untuk semua jenis yang dijelaskan:
Jangan gunakan
len
untuk menguji daftar kosong atau kosongUntuk menguji panjang tertentu, tentu saja, cukup menguji kesetaraan:
Tetapi ada kasus khusus untuk pengujian untuk daftar panjang nol atau kebalikannya. Dalam hal itu, jangan menguji kesetaraan.
Juga, jangan lakukan:
Sebaliknya, lakukan saja:
atau
Saya jelaskan mengapa di sini tetapi singkatnya,
if items
atauif not items
keduanya lebih mudah dibaca dan lebih berkinerja.sumber
Walaupun ini mungkin tidak berguna karena fakta bahwa itu akan jauh lebih masuk akal sebagai fungsi "di luar kotak", peretasan yang cukup sederhana adalah membangun kelas dengan
length
properti:Anda dapat menggunakannya seperti ini:
Pada dasarnya, ini persis identik dengan objek daftar, dengan manfaat tambahan dari memiliki
length
properti ramah-OOP .Seperti biasa, jarak tempuh Anda mungkin bervariasi.
sumber
length = property(len)
dan melewatkan fungsi pembungkus satu baris dan menyimpan dokumentasi / introspeksilen
dengan properti Anda.Selain itu
len
Anda juga dapat menggunakanoperator.length_hint
(membutuhkan Python 3.4+). Untuk yang normallist
keduanya sama, tetapilength_hint
memungkinkan untuk mendapatkan panjang daftar-iterator, yang bisa berguna dalam keadaan tertentu:Tapi
length_hint
menurut definisi hanya "petunjuk", jadi sebagian besar waktulen
lebih baik.Saya telah melihat beberapa jawaban yang menyarankan mengakses
__len__
. Ini baik-baik saja ketika berhadapan dengan kelas bawaan sepertilist
, tetapi bisa menimbulkan masalah dengan kelas khusus, karenalen
(danlength_hint
) menerapkan beberapa pemeriksaan keamanan. Misalnya, keduanya tidak memungkinkan panjang negatif atau panjang yang melebihi nilai tertentu (sys.maxsize
nilai). Jadi selalu lebih aman menggunakanlen
fungsi daripada__len__
metode!sumber
Menjawab pertanyaan Anda sebagai contoh juga diberikan sebelumnya:
sumber
__foo__
.: ini hanya sebuah konvensi, cara bagi sistem Python untuk menggunakan nama yang tidak akan bertentangan dengan nama pengguna. 2_foo
.: ini hanya sebuah konvensi, cara bagi pemrogram untuk menunjukkan bahwa variabel bersifat pribadi (apa pun artinya dengan Python). 3__foo
.: ini memiliki arti nyata: penerjemah menggantikan nama ini dengan_classname__foo
cara untuk memastikan bahwa nama tersebut tidak akan tumpang tindih dengan nama yang serupa di kelas lain. * Tidak ada bentuk garis bawah yang memiliki makna di dunia Python. * Tidak ada perbedaan antara kelas, variabel, global, dll dalam konvensi ini.Dan untuk kelengkapan (terutama pendidikan), dimungkinkan tanpa menggunakan
len()
fungsi. Saya tidak akan memaafkan ini sebagai opsi yang baik JANGAN PROGRAM SEPERTI INI DI PYTHON , tetapi ini melayani tujuan untuk mempelajari algoritma.(Usus besar dalam
list[:]
adalah implisit dan karena itu juga opsional.)Pelajaran di sini untuk programmer baru adalah: Anda tidak bisa mendapatkan jumlah item dalam daftar tanpa menghitungnya di beberapa titik. Pertanyaannya menjadi: kapan waktu yang tepat untuk menghitungnya? Misalnya, kode berperforma tinggi seperti sambungkan sistem panggilan untuk soket (ditulis dalam C)
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
, tidak menghitung panjang elemen (memberikan tanggung jawab itu pada kode panggilan). Perhatikan bahwa panjang alamat dilewatkan untuk menyimpan langkah penghitungan panjang terlebih dahulu? Pilihan lain: secara komputasi, mungkin masuk akal untuk melacak jumlah item saat Anda menambahkannya dalam objek yang Anda lewati. Pikiran bahwa ini membutuhkan lebih banyak ruang dalam memori. Lihat jawaban Naftuli Kay .Contoh melacak panjang untuk meningkatkan kinerja sambil mengambil lebih banyak ruang di memori. Perhatikan bahwa saya tidak pernah menggunakan fungsi len () karena panjangnya dilacak:
sumber
for item in list[:]:
? Mengapa tidakfor item in list:
? Juga, saya gunakan+= 1
untuk menambah.Dalam hal bagaimana
len()
sebenarnya bekerja, ini adalah implementasi C-nya :Py_ssize_t
adalah panjang maksimum yang dapat dimiliki objek.PyObject_Size()
adalah fungsi yang mengembalikan ukuran suatu objek. Jika tidak dapat menentukan ukuran suatu objek, ia mengembalikan -1. Dalam hal ini, blok kode ini akan dieksekusi:Dan sebagai hasilnya muncul pengecualian. Jika tidak, blok kode ini akan dieksekusi:
res
yang merupakanC
bilangan bulat, diubah menjadi pythonlong
dan dikembalikan. Semua bilangan bulat python disimpan sepertilongs
sejak Python 3.sumber