如何获取列表项中的元素数?
items = ["apple", "orange", "banana"]
# There are 3 items.
如何获取列表项中的元素数?
items = ["apple", "orange", "banana"]
# There are 3 items.
当前回答
除了len之外,您还可以使用operator.length_hint(需要Python 3.4+)。对于普通列表,两者都是等效的,但length_hint可以获得列表迭代器的长度,这在某些情况下可能很有用:
>>> 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
但根据定义,length_hint只是一个“提示”,所以大多数时候len更好。
我看到了几个建议访问___ len__的答案。在处理像list这样的内置类时,这是可以的,但这可能会导致自定义类出现问题,因为len(和length_hint)实现了一些安全检查。例如,两者都不允许负长度或超过某个值(sys.maxsize值)的长度。因此,使用len函数而不是__len__方法总是更安全!
其他回答
除了len之外,您还可以使用operator.length_hint(需要Python 3.4+)。对于普通列表,两者都是等效的,但length_hint可以获得列表迭代器的长度,这在某些情况下可能很有用:
>>> 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
但根据定义,length_hint只是一个“提示”,所以大多数时候len更好。
我看到了几个建议访问___ len__的答案。在处理像list这样的内置类时,这是可以的,但这可能会导致自定义类出现问题,因为len(和length_hint)实现了一些安全检查。例如,两者都不允许负长度或超过某个值(sys.maxsize值)的长度。因此,使用len函数而不是__len__方法总是更安全!
len()函数可以用于Python中的几种不同类型——内置类型和库类型。例如:
>>> len([1, 2, 3])
3
有三种方法可以找到列表中元素的长度。我将在这里比较这三种方法与性能分析。
方法1:使用len()
items = []
items.append("apple")
items.append("orange")
items.append("banana")
print(len(items))
输出:
3
方法2:使用Naive Counter方法
items = []
items.append("apple")
items.append("orange")
items.append("banana")
counter = 0
for i in items:
counter = counter + 1
print(counter)
输出:
3
方法3:使用length_hint()
items = []
items.append("apple")
items.append("orange")
items.append("banana")
from operator import length_hint
list_len_hint = length_hint(items)
print(list_len_hint)
输出:
3
性能分析–Naive vs len()vs length_hint()
注意:为了进行比较,我将输入列表更改为一个大集合,该集合可以提供大量的时间差来比较方法。
items = list(range(100000000))
# Performance Analysis
from operator import length_hint
import time
# Finding length of list
# using loop
# Initializing counter
start_time_naive = time.time()
counter = 0
for i in items:
# incrementing counter
counter = counter + 1
end_time_naive = str(time.time() - start_time_naive)
# Finding length of list
# using len()
start_time_len = time.time()
list_len = len(items)
end_time_len = str(time.time() - start_time_len)
# Finding length of list
# using length_hint()
start_time_hint = time.time()
list_len_hint = length_hint(items)
end_time_hint = str(time.time() - start_time_hint)
# Printing Times of each
print("Time taken using naive method is : " + end_time_naive)
print("Time taken using len() is : " + end_time_len)
print("Time taken using length_hint() is : " + end_time_hint)
输出:
Time taken using naive method is : 7.536813735961914
Time taken using len() is : 0.0
Time taken using length_hint() is : 0.0
结论
可以清楚地看到,与其他两种方法相比,naive所花费的时间非常长,因此len()和length_hint()是最好的选择。
为了完整性(主要是教育性的),可以不使用len()函数。我不会容忍这是一个很好的选择,不要在巨蟒身上这样编程,但它有助于学习算法。
def count(list): # list is an iterable object but no type checking here!
item_count = 0
for item in list:
item_count += 1
return item_count
count([1,2,3,4,5])
(列表对象必须是可迭代的,由节中的for..暗示。)
对于新程序员来说,这里的教训是:如果不在某个时间点对项目进行计数,就无法获得列表中的项目数。问题变成了:什么时候是计算它们的好时机?例如,高性能代码,如套接字的connect系统调用(用C编写)connect(int sockfd,const struct sockaddr*addr,socklen_t addrlen);,不计算元素的长度(将该责任赋予调用代码)。请注意,地址的长度是为了保存首先计算长度的步骤而传递的?另一种选择是:在计算上,当您将项目添加到传递的对象中时,跟踪项目的数量可能是有意义的。请注意,这会占用更多的内存空间。看看Naftuli Kay的回答。
跟踪长度以提高性能同时占用更多内存空间的示例。注意,我从不使用len()函数,因为长度是跟踪的:
class MyList(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 class
def __iter__(self):
for elem in self._data:
yield elem
def add(self, elem):
self._data.append(elem)
self.length += 1
def 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
如何获取列表的长度?
要查找列表中的元素数,请使用内置函数len:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
现在:
len(items)
返回3。
解释
Python中的所有内容都是一个对象,包括列表。在C实现中,所有对象都有某种类型的头。
列表和Python中具有“大小”的其他类似内置对象尤其具有一个名为ob_size的属性,其中缓存了对象中的元素数。因此,检查列表中对象的数量非常快。
但如果要检查列表大小是否为零,请不要使用len,而是将列表放在布尔上下文中,如果为空,则将其视为False,如果为非空,则视为True。
从文档中
长度
返回对象的长度(项目数)。参数可以是序列(例如字符串、字节、元组、列表或范围)或集合(如字典、集合或冻结集合)。
len是用__len__实现的,来自数据模型文档:
对象__len__(自己)
调用以实现内置函数len()。应该返回对象的长度,一个大于等于0的整数。此外定义__nonzero_()[在Python 2中或__bool_()在Python 3中]方法,其__len__()方法返回零在布尔上下文中被认为是假的。
我们还可以看到__len__是一种列表方法:
items.__len__()
返回3。
内置类型,可以获得长度
事实上,我们可以看到所有描述类型的信息:
>>> all(hasattr(cls, '__len__') for cls in (str, bytes, tuple, list,
range, dict, set, frozenset))
True
不要使用len测试空列表或非空列表
当然,要测试特定长度,只需测试相等性即可:
if len(items) == required_length:
...
但是对于零长度列表或相反列表的测试有一个特殊的情况。在这种情况下,不要测试是否相等。
此外,请勿执行以下操作:
if len(items):
...
相反,只需执行以下操作:
if items: # Then we have some items, not empty!
...
or
if not items: # Then we have an empty list!
...
我在这里解释了为什么,但简而言之,if项或if项都更可读,更具性能。