Arr .__ len __ () est-il le moyen préféré pour obtenir la longueur d'un tableau en Python?

728

En Python , les éléments suivants sont-ils le seul moyen d'obtenir le nombre d'éléments?

arr.__len__()

Si oui, pourquoi l'étrange syntaxe?

Joan Venge
la source

Réponses:

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

La même chose fonctionne pour les tuples:

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

Et les chaînes, qui ne sont en réalité que des tableaux de caractères:

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

Cela a été fait intentionnellement de cette façon afin que les listes, tuples et autres types de conteneurs ou itérables n'aient pas tous besoin d'implémenter explicitement une .length()méthode publique , à la place, vous pouvez simplement vérifier len()tout ce qui implémente la __len__()méthode `` magique '' .

Bien sûr, cela peut sembler redondant, mais les implémentations de vérification de longueur peuvent varier considérablement, même dans le même langage. Il n'est pas rare de voir un type de collection utiliser une .length()méthode tandis qu'un autre type utilise une .lengthpropriété, tandis qu'un autre encore utilise .count(). Le fait d'avoir un mot clé au niveau de la langue unifie le point d'entrée pour tous ces types. Ainsi, même les objets que vous ne considérez pas comme des listes d'éléments peuvent toujours être vérifiés en longueur. Cela inclut les chaînes, les files d'attente, les arbres, etc.

La nature fonctionnelle de len()se prête également bien aux styles fonctionnels de programmation.

lengths = map(len, list_of_containers)
Soviut
la source
8
len () est une commande de langage, __len __ () est une méthode sur les types de conteneurs.
Soviut
33
len () est une fonction globale intégrée; __len __ () est une méthode que l'objet peut implémenter. len (foo) finit généralement par appeler foo .__ len __ ().
Tim Lesher
13
Vous mentionnez qu'en fournissant len ​​(), chaque conteneur n'a pas à implémenter une méthode .length (), mais en quoi est-ce différent, si chaque type implémente toujours une méthode __len __ () qui est de toute façon appelée par len ()? Les différents types de conteneurs sont-ils traités différemment par len ()?
Simon B. Jensen
10
@Simon: le bit sur "n'ont pas tous besoin d'implémenter .length ()" est déroutant. Les types de conteneurs doivent encore implémenter une méthode pour renvoyer leur longueur; le fait est que c'est un protocole standardisé, pas une méthode ad hoc que vous devez rechercher pour chaque type. Les doubles soulignés signifient cela.
Carl Meyer
16
Je suis d'accord avec Carl Meyer - dire qu'il n'est pas "nécessaire d'implémenter explicitement" une méthode publique .length () est trompeur et fondamentalement incorrect. N'importe quoi devra toujours implémenter len , et peut toujours simplement implémenter sa propre méthode de longueur nommée comme il veut - en contournant la fonction len. Donc, vraiment, je vois cela comme une bizarrerie arbitraire qui correspond à la façon dont Guido voit le monde. Cela n'a probablement rien à voir avec un raisonnement universel.
BT
52

La façon dont vous prenez une longueur de tout ce qui a du sens (une liste, un dictionnaire, un tuple, une chaîne, ...) est de l'appeler len.

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

La raison de la syntaxe "étrange" est que python se traduit len(object)en interne object.__len__(). Cela s'applique à tout objet. Donc, si vous définissez une classe et qu'il est logique qu'elle ait une longueur, définissez simplement une __len__()méthode dessus et alors on peut invoquer lences instances.

rz.
la source
23

Python utilise la dactylographie de canard : il ne se soucie pas de ce que l'objet est , tant qu'il a l'interface appropriée pour la situation. Lorsque vous appelez la fonction intégrée len () sur un objet, vous appelez en fait sa méthode interne __len__. Un objet personnalisé peut implémenter cette interface et len ​​() retournera la réponse, même si l'objet n'est pas conceptuellement une séquence.

Pour une liste complète des interfaces, consultez ici: http://docs.python.org/reference/datamodel.html#basic-customization

UncleZeiv
la source
23

La meilleure façon d'obtenir la longueur d'un objet python est de le passer en argument à la lenfonction. En interne, python tentera alors d'appeler la __len__méthode spéciale de l'objet qui a été transmis.

David Locke
la source
22

Utilisez simplement len(arr):

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

vous pouvez utiliser len(arr) comme suggéré dans les réponses précédentes pour obtenir la longueur du tableau. Si vous voulez les dimensions d'un tableau 2D, vous pouvez utiliser la arr.shapehauteur et la largeur de retour

Ahmed Abobakr
la source
7

len(list_name)La fonction prend list comme paramètre et appelle la __len__()fonction list .

Harun ERGUL
la source
1

Python suggère aux utilisateurs d'utiliser len()au lieu de __len__()pour plus de cohérence, tout comme d'autres gars l'ont dit. Cependant, il existe d'autres avantages:

Pour certains types comme intégré dans list, str, bytearrayet ainsi de suite, la mise en œuvre de Cython len()prend un raccourci. Il renvoie directement le ob_sizedans une structure C, ce qui est plus rapide que d'appeler __len__().

Si vous êtes intéressé par de tels détails, vous pouvez lire le livre intitulé "Fluent Python" de Luciano Ramalho. Il contient de nombreux détails intéressants et peut vous aider à mieux comprendre Python.

JOHNKYON
la source