Czy arr .__ len __ () jest preferowanym sposobem uzyskania długości tablicy w Pythonie?

727

Czy w Pythonie następujący sposób uzyskania liczby elementów jest następujący?

arr.__len__()

Jeśli tak, to dlaczego ta dziwna składnia?

Joan Venge
źródło

Odpowiedzi:

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

To samo działa w przypadku krotek:

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

I ciągi, które tak naprawdę są tylko tablicami znaków:

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

Zostało to celowo wykonane w taki sposób , aby listy, krotki i inne typy kontenerów lub iteracje nie musiały jawnie implementować .length()metody publicznej , zamiast tego można po prostu sprawdzić len()wszystko, co implementuje __len__()metodę „magii” .

Oczywiście może się to wydawać zbędne, ale implementacje sprawdzania długości mogą się znacznie różnić, nawet w tym samym języku. Często zdarza się, że jeden typ kolekcji korzysta z .length()metody, podczas gdy inny typ korzysta z .lengthwłaściwości, podczas gdy inny używa .count(). Posiadanie słowa kluczowego na poziomie języka ujednolica punkt wejścia dla wszystkich tych typów. Tak więc nawet obiekty, których nie możesz uznać za listy elementów, nadal mogą być sprawdzane pod względem długości. Obejmuje to ciągi, kolejki, drzewa itp.

Funkcjonalny charakter len()nadaje się również do funkcjonalnych stylów programowania.

lengths = map(len, list_of_containers)
Soviut
źródło
8
len () to polecenie języka, __len __ () to metoda na typach kontenerów.
Soviut
33
len () jest globalną, wbudowaną funkcją; __len __ () to metoda, którą obiekt może zaimplementować. len (foo) zwykle kończy się wywołaniem foo .__ len __ ().
Tim Lesher
13
Wspominasz, że dostarczając len (), każdy kontener nie musi implementować metody .length (), ale czym to się różni, jeśli każdy typ nadal implementuje metodę __len __ (), która i tak jest wywoływana przez len ()? Czy różne typy kontenerów są obsługiwane inaczej przez len ()?
Simon B. Jensen
10
@ Simon: fragment o „nie wszyscy muszą implementować .length ()” jest mylący. Typy kontenerów nadal muszą wdrożyć metodę zwracania ich długości; Chodzi o to, że jest to ustandaryzowany protokół, a nie metoda ad-hoc, którą należy wyszukać dla każdego typu. Podwójne podkreślenia to oznaczają.
Carl Meyer,
16
Zgadzam się z Carlem Meyerem - stwierdzenie, że „nie trzeba jawnie implementować” publicznej metody .length (), jest mylące, a w swej istocie niepoprawne. Wszystko będzie nadal musiało zaimplementować len i zawsze może po prostu zaimplementować własną metodę długości o dowolnej nazwie - omijając funkcję len. Naprawdę uważam to za jakąś arbitralną dziwność, która pasuje do tego, jak Guido postrzega świat. Prawdopodobnie nie ma to nic wspólnego z żadnym uniwersalnym rozumowaniem.
BT
52

Sposób, w jaki bierzesz długość wszystkiego, co ma sens (lista, słownik, krotka, ciąg, ...), polega na wywołaniu lengo.

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

Powodem składni „dziwne” jest to, że wewnętrznie pyton przekłada len(object)się object.__len__(). Dotyczy to każdego obiektu. Jeśli więc definiujesz jakąś klasę i ma sens, aby miała ona długość, po prostu zdefiniuj __len__()na niej metodę, a następnie będziesz mógł wywoływać lente instancje.

rz.
źródło
23

Python używa kaczka wpisując : to nie dba o to, co obiekt jest tak długo, jak to ma odpowiedni interfejs do sytuacji. Kiedy wywołujesz wbudowaną funkcję len () na obiekcie, w rzeczywistości wywołujesz jego wewnętrzną metodę __len__. Obiekt niestandardowy może zaimplementować ten interfejs, a len () zwróci odpowiedź, nawet jeśli obiekt nie jest koncepcyjnie sekwencją.

Pełna lista interfejsów znajduje się tutaj: http://docs.python.org/reference/datamodel.html#basic-customization

UncleZeiv
źródło
23

Preferowanym sposobem uzyskania długości dowolnego obiektu python jest przekazanie go jako argumentu do lenfunkcji. Wewnętrznie Python spróbuje następnie wywołać specjalną __len__metodę przekazanego obiektu.

David Locke
źródło
22

Po prostu użyj len(arr):

>>> import array
>>> arr = array.array('i')
>>> arr.append('2')
>>> arr.__len__()
1
>>> len(arr)
1
Tim Lesher
źródło
10

możesz użyć, len(arr) jak sugerowano w poprzednich odpowiedziach, aby uzyskać długość tablicy. W przypadku, gdy chcesz mieć wymiary tablicy 2D, możesz użyć arr.shapezwrotów wysokości i szerokości

Ahmed Abobakr
źródło
7

len(list_name)Funkcja przyjmuje listę jako parametr i wywołuje __len__()funkcję listy .

Harun ERGUL
źródło
1

Python sugeruje użytkownikom używanie len()zamiast __len__()spójności, tak jak mówili inni faceci. Istnieją jednak inne korzyści:

Dla niektórych typów wbudowanych, takich jak list, str, bytearrayi tak dalej, realizacja Cython of len()zajmuje skrót. Zwraca bezpośrednio ob_sizestrukturę C, która jest szybsza niż wywołanie __len__().

Jeśli jesteś zainteresowany takimi szczegółami, możesz przeczytać książkę „Fluent Python” Luciano Ramalho. Zawiera wiele interesujących szczegółów i może pomóc w lepszym zrozumieniu Pythona.

JOHNKYON
źródło