Você está obviamente pedindo o número de elementos na lista. Se um pesquisador chegar aqui procurando o tamanho do objeto na memória, esta é a pergunta e as respostas reais que ele está procurando: Como determinar o tamanho de um objeto no Python?
Aaron Hall
Respostas:
2640
A len()função pode ser usada com vários tipos diferentes em Python - tipos internos e tipos de biblioteca. Por exemplo:
>>> len([1,2,3])3
A documentação oficial 2.x está aqui:
A documentação oficial 3.x está aqui:len() len()
Tudo no Python é um objeto, incluindo listas. Todos os objetos têm um cabeçalho de algum tipo na implementação C.
As listas e outros objetos internos similares com um "tamanho" no Python, em particular, têm um atributo chamado ob_size, onde o número de elementos no objeto é armazenado em cache. Portanto, verificar o número de objetos em uma lista é muito rápido.
Retorna o comprimento (o número de itens) de um objeto. O argumento pode ser uma sequência (como uma sequência de caracteres, bytes, tupla, lista ou intervalo) ou uma coleção (como um dicionário, conjunto ou conjunto congelado).
lené implementado com __len__, a partir dos documentos do modelo de dados :
object.__len__(self)
Chamado para implementar a função interna len(). Deve retornar o comprimento do objeto, um número inteiro> = 0. Além disso, um objeto que não define um método __nonzero__()[no Python 2 ou __bool__()no Python 3] e cujo __len__()método retorna zero é considerado falso em um contexto booleano.
E também podemos ver que __len__é um método de lista:
items.__len__()
retorna 3.
Tipos internos você pode obter o len(comprimento) de
De fato, vemos que podemos obter essas informações para todos os tipos descritos:
Embora isso possa não ser útil devido ao fato de que faria muito mais sentido ser uma funcionalidade "pronta para uso", um truque bastante simples seria criar uma classe com uma lengthpropriedade:
class slist(list):@propertydef length(self):return len(self)
Você pode usá-lo assim:
>>> l = slist(range(10))>>> l.length
10>>>print l
[0,1,2,3,4,5,6,7,8,9]
Essencialmente, é exatamente idêntico a um objeto de lista, com o benefício adicional de ter uma lengthpropriedade compatível com OOP .
só para você saber, você pode simplesmente fazer length = property(len)e pular a função de wrapper de uma linha e manter a documentação / introspecção de lensua propriedade.
Tadhg McDonald-Jensen
17
Além disso, lenvocê também pode usar operator.length_hint(requer Python 3.4+). Para um normal, listambos são equivalentes, mas length_hintpossibilitam obter o comprimento de um iterador de lista, o que pode ser útil em determinadas circunstâncias:
>>>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
Mas, length_hintpor definição, é apenas uma "dica", então na maioria das vezes lené melhor.
Eu já vi várias respostas sugerindo acessar __len__. Está tudo bem ao lidar com classes internas como list, mas pode levar a problemas com classes personalizadas, porque len(e length_hint) implementam algumas verificações de segurança. Por exemplo, ambos não permitem comprimentos negativos ou comprimentos que excedam um determinado valor (o sys.maxsizevalor). Portanto, é sempre mais seguro usar a lenfunção em vez do __len__método!
No Python, os nomes que começam com sublinhados são métodos semanticamente não públicos e não devem ser usados pelos usuários.
Aaron Hall
2
1 __foo__.: isso é apenas uma convenção, uma maneira de o sistema Python usar nomes que não entrem em conflito com os nomes de usuário. 2 _foo.: esta é apenas uma convenção, uma maneira do programador indicar que a variável é privada (o que quer que isso signifique em Python). 3 __foo.: isso tem um significado real: o intérprete substitui esse nome _classname__foopor uma maneira de garantir que o nome não se sobreponha a um nome semelhante em outra classe. * Nenhuma outra forma de sublinhado tem significado no mundo Python. * Não há diferença entre classe, variável, global, etc. nessas convenções.
Shai Alon
4
Esta sessão de perguntas e respostas explica por que você não deve usar os métodos especiais diretamente como usuário: stackoverflow.com/q/40272161/541136
Aaron Hall
@ AaronHall, mas para a função len é quase o mesmo. Pode ser mais rápido para variáveis muito grandes. No entanto, entendi seu argumento e devemos usar len (obj) e não obj .__ len __ ().
Shai Alon
7
E para completude (principalmente educacional), é possível sem o uso da len()função. Eu não aceitaria isso como uma boa opção NÃO PROGRAMA COMO ESTE NO PYTHON , mas serve a um propósito para o aprendizado de algoritmos.
(O sinal de dois pontos list[:]está implícito e, portanto, também é opcional.)
A lição aqui para novos programadores é: Você não pode obter o número de itens em uma lista sem contá-los em algum momento. A questão é: quando é um bom momento para contá-los? Por exemplo, código de alto desempenho, como a chamada do sistema de conexão de soquetes (escrita em C) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, não calcula o comprimento dos elementos (atribuindo essa responsabilidade ao código de chamada). Observe que o comprimento do endereço é passado adiante para salvar a etapa de contar o comprimento primeiro? Outra opção: computacionalmente, pode fazer sentido acompanhar o número de itens à medida que você os adiciona ao objeto que você passa. Lembre-se de que isso ocupa mais espaço na memória. Veja a resposta de Naftuli Kay .
Exemplo de como acompanhar o comprimento para melhorar o desempenho e ocupar mais espaço na memória. Observe que eu nunca uso a função len () porque o comprimento é rastreado:
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
Por que for item in list[:]:? Por que não for item in list:? Além disso, eu usaria += 1para incrementar.
Granny Aching
@GrannyAching Mencionei explicitamente os dois pontos opcionais (especificador de intervalo). Deixei o especificador de intervalo lá para fins educacionais - é benéfico saber que está implícito. Um tipo de lista [] também é inferido, como você sugere - equivalente ao meu código. O operador de incremento também é equivalente a adicionar 1 a uma variável existente, ainda mais curta em todos os casos. Então, eu concordo que deve ser usado se esse for o seu raciocínio. De qualquer forma, esse código não deve ser colocado em produção em nenhum lugar (exceto ao aprender programação).
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_té o comprimento máximo que o objeto pode ter. PyObject_Size()é uma função que retorna o tamanho de um objeto. Se não puder determinar o tamanho de um objeto, ele retornará -1. Nesse caso, este bloco de código será executado:
if(res <0){assert(PyErr_Occurred());return NULL;}
E uma exceção é gerada como resultado. Caso contrário, este bloco de código será executado:
returnPyLong_FromSsize_t(res);
resque é um Cnúmero inteiro, é convertido em python longe retornado. Todos os números inteiros do python são armazenados como longsdesde o Python 3.
Respostas:
A
len()
função pode ser usada com vários tipos diferentes em Python - tipos internos e tipos de biblioteca. Por exemplo:A documentação oficial 2.x está aqui: A documentação oficial 3.x está aqui:
len()
len()
fonte
Para encontrar o tamanho de uma lista, use a função interna
len
:E agora:
retorna 3.
Explicação
Tudo no Python é um objeto, incluindo listas. Todos os objetos têm um cabeçalho de algum tipo na implementação C.
As listas e outros objetos internos similares com um "tamanho" no Python, em particular, têm um atributo chamado
ob_size
, onde o número de elementos no objeto é armazenado em cache. Portanto, verificar o número de objetos em uma lista é muito rápido.Mas se você estiver verificando se o tamanho da lista é zero ou não, não use
len
- em vez disso, coloque a lista em um contexto booleano - ele será tratado como False se estiver vazio, True caso contrário .Dos documentos
len(s)
len
é implementado com__len__
, a partir dos documentos do modelo de dados :object.__len__(self)
E também podemos ver que
__len__
é um método de lista:retorna 3.
Tipos internos você pode obter o
len
(comprimento) deDe fato, vemos que podemos obter essas informações para todos os tipos descritos:
Não use
len
para testar uma lista vazia ou não vaziaPara testar um comprimento específico, é claro, basta testar a igualdade:
Mas há um caso especial para testar uma lista de tamanho zero ou o inverso. Nesse caso, não teste a igualdade.
Além disso, não faça:
Em vez disso, basta:
ou
Eu explico o porquê aqui, mas em resumo,
if items
ouif not items
é mais legível e com melhor desempenho.fonte
Embora isso possa não ser útil devido ao fato de que faria muito mais sentido ser uma funcionalidade "pronta para uso", um truque bastante simples seria criar uma classe com uma
length
propriedade:Você pode usá-lo assim:
Essencialmente, é exatamente idêntico a um objeto de lista, com o benefício adicional de ter uma
length
propriedade compatível com OOP .Como sempre, sua milhagem pode variar.
fonte
length = property(len)
e pular a função de wrapper de uma linha e manter a documentação / introspecção delen
sua propriedade.Além disso,
len
você também pode usaroperator.length_hint
(requer Python 3.4+). Para um normal,list
ambos são equivalentes, maslength_hint
possibilitam obter o comprimento de um iterador de lista, o que pode ser útil em determinadas circunstâncias:Mas,
length_hint
por definição, é apenas uma "dica", então na maioria das vezeslen
é melhor.Eu já vi várias respostas sugerindo acessar
__len__
. Está tudo bem ao lidar com classes internas comolist
, mas pode levar a problemas com classes personalizadas, porquelen
(elength_hint
) implementam algumas verificações de segurança. Por exemplo, ambos não permitem comprimentos negativos ou comprimentos que excedam um determinado valor (osys.maxsize
valor). Portanto, é sempre mais seguro usar alen
função em vez do__len__
método!fonte
Respondendo à sua pergunta como os exemplos também foram fornecidos anteriormente:
fonte
__foo__
.: isso é apenas uma convenção, uma maneira de o sistema Python usar nomes que não entrem em conflito com os nomes de usuário. 2_foo
.: esta é apenas uma convenção, uma maneira do programador indicar que a variável é privada (o que quer que isso signifique em Python). 3__foo
.: isso tem um significado real: o intérprete substitui esse nome_classname__foo
por uma maneira de garantir que o nome não se sobreponha a um nome semelhante em outra classe. * Nenhuma outra forma de sublinhado tem significado no mundo Python. * Não há diferença entre classe, variável, global, etc. nessas convenções.E para completude (principalmente educacional), é possível sem o uso da
len()
função. Eu não aceitaria isso como uma boa opção NÃO PROGRAMA COMO ESTE NO PYTHON , mas serve a um propósito para o aprendizado de algoritmos.(O sinal de dois pontos
list[:]
está implícito e, portanto, também é opcional.)A lição aqui para novos programadores é: Você não pode obter o número de itens em uma lista sem contá-los em algum momento. A questão é: quando é um bom momento para contá-los? Por exemplo, código de alto desempenho, como a chamada do sistema de conexão de soquetes (escrita em C)
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
, não calcula o comprimento dos elementos (atribuindo essa responsabilidade ao código de chamada). Observe que o comprimento do endereço é passado adiante para salvar a etapa de contar o comprimento primeiro? Outra opção: computacionalmente, pode fazer sentido acompanhar o número de itens à medida que você os adiciona ao objeto que você passa. Lembre-se de que isso ocupa mais espaço na memória. Veja a resposta de Naftuli Kay .Exemplo de como acompanhar o comprimento para melhorar o desempenho e ocupar mais espaço na memória. Observe que eu nunca uso a função len () porque o comprimento é rastreado:
fonte
for item in list[:]:
? Por que nãofor item in list:
? Além disso, eu usaria+= 1
para incrementar.Em termos de como
len()
realmente funciona, esta é sua implementação em C :Py_ssize_t
é o comprimento máximo que o objeto pode ter.PyObject_Size()
é uma função que retorna o tamanho de um objeto. Se não puder determinar o tamanho de um objeto, ele retornará -1. Nesse caso, este bloco de código será executado:E uma exceção é gerada como resultado. Caso contrário, este bloco de código será executado:
res
que é umC
número inteiro, é convertido em pythonlong
e retornado. Todos os números inteiros do python são armazenados comolongs
desde o Python 3.fonte