Arr .__ len __ () é a maneira preferida de obter o comprimento de uma matriz em Python?

727

Em Python , a seguinte é a única maneira de obter o número de elementos?

arr.__len__()

Se sim, por que a sintaxe estranha?

Joan Venge
fonte

Respostas:

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

O mesmo funciona para tuplas:

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

E strings, que são realmente apenas matrizes de caracteres:

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

Foi intencionalmente feito dessa maneira, para que listas, tuplas e outros tipos de contêineres ou iteráveis ​​não precisassem implementar explicitamente um .length()método público ; em vez disso, você pode simplesmente verificar o len()que implementa o __len__()método 'mágico' .

Claro, isso pode parecer redundante, mas as implementações de verificação de comprimento podem variar consideravelmente, mesmo dentro do mesmo idioma. Não é incomum ver um tipo de coleção usar um .length()método, enquanto outro tipo usa uma .lengthpropriedade, enquanto outro usa .count(). Ter uma palavra-chave no nível do idioma unifica o ponto de entrada para todos esses tipos. Assim, mesmo objetos que você não considere serem listas de elementos ainda podem ser verificados por comprimento. Isso inclui strings, filas, árvores, etc.

A natureza funcional de len()também se presta bem a estilos funcionais de programação.

lengths = map(len, list_of_containers)
Soviut
fonte
8
len () é um comando de idioma, __len __ () é um método para tipos de contêineres.
Soviut 05/02/09
33
len () é uma função interna global; __len __ () é um método que o objeto pode implementar. len (foo) geralmente acaba chamando foo .__ len __ ().
Tim Lesher
13
Você menciona que, ao fornecer len (), cada contêiner não precisa implementar um método .length (), mas como isso é diferente, se cada tipo ainda implementa um método __len __ () que é chamado pelo len () de qualquer maneira? Diferentes tipos de contêiner são tratados de maneira diferente por len ()?
22416 Simon B Jensen
10
@ Simon: o pouco sobre "nem todos precisam implementar .length ()" é confuso. Os tipos de contêineres ainda precisam implementar um método para retornar seu comprimento; o ponto é que é um protocolo padronizado, não um método ad-hoc que você precisa procurar para cada tipo. Os sublinhados duplos significam isso.
246 Carl Meyer
16
Eu concordo com Carl Meyer - dizer que "não precisa implementar explicitamente" um método público .length () é enganoso e, no seu significado principal, incorreto. Qualquer coisa ainda precisará implementar o len , e sempre pode simplesmente implementar seu próprio método de comprimento, denominado o que eles quiserem - contornando a função len. Então, realmente, vejo isso como uma estranheza arbitrária que se encaixa na maneira como Guido vê o mundo. Provavelmente não tem nada a ver com nenhum raciocínio universal.
BT
52

A maneira como você escolhe um item para o qual faz sentido (uma lista, dicionário, tupla, string, ...) é invocá len-lo.

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

A razão para a sintaxe "estranha" é que internamente o python se traduz len(object)em object.__len__(). Isso se aplica a qualquer objeto. Portanto, se você está definindo alguma classe e faz sentido que ela tenha um comprimento, basta definir um __len__()método e, em seguida, é possível recorrer lena essas instâncias.

rz.
fonte
23

Python usa tipagem pato : ele não se preocupa com o que um objeto é , contanto que tem a interface apropriada para a situação na mão. Quando você chama a função interna len () em um objeto, na verdade está chamando seu método interno __len__. Um objeto personalizado pode implementar essa interface e len () retornará a resposta, mesmo que o objeto não seja conceitualmente uma sequência.

Para obter uma lista completa de interfaces, consulte aqui: http://docs.python.org/reference/datamodel.html#basic-customization

UncleZeiv
fonte
23

A maneira preferida de obter o comprimento de qualquer objeto python é passá-lo como argumento para a lenfunção. Internamente, o python tentará chamar o __len__método especial do objeto que foi passado.

David Locke
fonte
22

Basta usar len(arr):

>>> import array
>>> arr = array.array('i')
>>> arr.append('2')
>>> arr.__len__()
1
>>> len(arr)
1
Tim Lesher
fonte
10

você pode usar len(arr) como sugerido nas respostas anteriores para obter o comprimento da matriz. Caso deseje as dimensões de uma matriz 2D, você pode usar arr.shaperetornos de altura e largura

Ahmed Abobakr
fonte
7

len(list_name)A função recebe a lista como parâmetro e chama a __len__()função da lista .

Harun ERGUL
fonte
1

Python sugere que os usuários usem em len()vez de __len__()consistência, assim como outros caras disseram. No entanto, existem outros benefícios:

Para alguns tipos internos, como list, str, bytearraye assim por diante, a implementação Cython de len()toma um atalho. Retorna diretamente a ob_sizeestrutura C, que é mais rápida do que chamar __len__().

Se você estiver interessado em tais detalhes, poderá ler o livro "Fluent Python", de Luciano Ramalho. Existem muitos detalhes interessantes e podem ajudar você a entender o Python mais profundamente.

JOHNKYON
fonte