Arr .__ len __ () è il modo preferito per ottenere la lunghezza di un array in Python?


727

In Python , il seguente è l'unico modo per ottenere il numero di elementi?

arr.__len__()

Se è così, perché la strana sintassi?

Risposte:


1229
my_list = [1,2,3,4,5]
len(my_list)
# 5

Lo stesso vale per le tuple:

my_tuple = (1,2,3,4,5)
len(my_tuple)
# 5

E le stringhe, che sono in realtà solo matrici di personaggi:

my_string = 'hello world'
len(my_string)
# 11

È stato fatto intenzionalmente in questo modo in modo che elenchi, tuple e altri tipi di contenitori o iterabili non dovessero tutti implementare esplicitamente un .length()metodo pubblico , invece puoi semplicemente controllare len()tutto ciò che implementa il __len__()metodo "magico" .

Certo, questo può sembrare ridondante, ma le implementazioni del controllo della lunghezza possono variare considerevolmente, anche nella stessa lingua. Non è raro vedere un tipo di raccolta utilizzare un .length()metodo mentre un altro tipo utilizza una .lengthproprietà, mentre un altro ancora utilizza .count(). La presenza di una parola chiave a livello di lingua unifica il punto di ingresso per tutti questi tipi. Quindi anche gli oggetti che potresti non considerare come elenchi di elementi potrebbero essere ancora controllati in base alla lunghezza. Ciò include stringhe, code, alberi, ecc.

La natura funzionale di len()si presta bene anche a stili funzionali di programmazione.

lengths = map(len, list_of_containers)

8
len () è un comando di lingua, __len __ () è un metodo sui tipi di contenitore.
Soviet

33
len () è una funzione globale integrata; __len __ () è un metodo che l'oggetto può implementare. len (foo) di solito finisce per chiamare foo .__ len __ ().
Tim Lesher,

13
Dici che fornendo len () ogni container non deve implementare un metodo .length (), ma come è diverso, se ogni tipo implementa ancora un metodo __len __ () che viene comunque chiamato da len ()? I diversi tipi di container sono gestiti in modo diverso da len ()?
Simon B. Jensen,

10
@Simon: il bit su "non tutti hanno bisogno di implementare .length ()" è confuso. I tipi di contenitore devono ancora implementare un metodo per restituire la loro lunghezza; il punto è che è un protocollo standardizzato, non un metodo ad hoc che devi cercare per ogni tipo. I doppi trattini bassi lo indicano.
Carl Meyer,

16
Concordo con Carl Meyer: affermare che non "è necessario implementare esplicitamente" un metodo .length () pubblico è fuorviante e, nel suo significato fondamentale, errato. Qualunque cosa dovrà ancora implementare len e potrà sempre semplicemente implementare il proprio metodo di lunghezza denominato come preferiscono, aggirando la funzione len. Quindi davvero vedo questo come una stranezza arbitraria che si adatta a come Guido vede il mondo. Probabilmente non ha nulla a che fare con alcun ragionamento universale.
BT,

52

Il modo in cui prendi una parte di tutto ciò per cui ha senso (un elenco, un dizionario, una tupla, una stringa, ...) è chiamarlo len.

l = [1,2,3,4]
s = 'abcde'
len(l) #returns 4
len(s) #returns 5

La ragione per la sintassi "strana" è che internamente pitone si traduce len(object)in object.__len__(). Questo vale per qualsiasi oggetto. Quindi, se stai definendo una classe e ha senso che abbia una lunghezza, basta definire un __len__()metodo su di essa e quindi si può chiamare lenquelle istanze.


23

Python usa duck typing : essa non si preoccupa di quello che un oggetto è , fintanto che ha l'interfaccia appropriata per la situazione a portata di mano. Quando si chiama la funzione integrata len () su un oggetto, si sta effettivamente chiamando il suo metodo __len__ interno. Un oggetto personalizzato può implementare questa interfaccia e len () restituirà la risposta, anche se l'oggetto non è concettualmente una sequenza.

Per un elenco completo delle interfacce, dai un'occhiata qui: http://docs.python.org/reference/datamodel.html#basic-customization


23

Il modo preferito per ottenere la lunghezza di qualsiasi oggetto Python è passarlo come argomento alla lenfunzione. Internamente, python tenterà quindi di chiamare il __len__metodo speciale dell'oggetto che è stato passato.


22

Usa solo len(arr):

>>> import array
>>> arr = array.array('i')
>>> arr.append('2')
>>> arr.__len__()
1
>>> len(arr)
1

10

è possibile utilizzare len(arr) come suggerito nelle risposte precedenti per ottenere la lunghezza dell'array. Nel caso in cui desideri le dimensioni di un array 2D, puoi utilizzare l' arr.shapealtezza e la larghezza dei ritorni


7

len(list_name)La funzione prende la lista come parametro e chiama la __len__()funzione della lista .


1

Python suggerisce agli utenti di utilizzare len()invece che __len__()per coerenza, proprio come altri ragazzi hanno detto. Tuttavia, ci sono altri vantaggi:

Per alcuni tipi predefiniti come list, str, bytearraye così via, l'attuazione di Cython len()prende un collegamento. Restituisce direttamente ob_sizein una struttura C, che è più veloce della chiamata __len__().

Se sei interessato a tali dettagli, potresti leggere il libro "Fluent Python" di Luciano Ramalho. Ci sono molti dettagli interessanti in esso e possono aiutarti a capire Python in modo più approfondito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.