如何获取列表中的元素数量?

考虑以下:

items = []
items.append("apple")
items.append("orange")
items.append("banana")

# FAKE METHOD:
items.amount()  # Should return 3

如何获取列表items的元素数?

答案

len()函数可与 Python 中的几种不同类型一起使用 - 内置类型和库类型。例如:

>>> len([1,2,3])
3

官方 2.x 文档在这里: len()
正式的 3.x 文档在这里: len()

如何获得列表的大小?

要查找列表的大小,请使用内置函数len

items = []
items.append("apple")
items.append("orange")
items.append("banana")

现在:

len(items)

返回 3。

说明

Python 中的所有内容都是一个对象,包括列表。在 C 实现中,所有对象都有某种头。

列表和其他类似的内置对象在 Python 中具有 “大小”,尤其是具有一个名为ob_size的属性,其中缓存了对象中元素的数量。因此,检查列表中对象的数量非常快。

但是,如果您要检查列表大小是否为零,请不要使用len而是将列表放在布尔值上下文中 - 如果为空,则将其视为 False,否则将其视为 True

来自文档

len(s)

返回对象的长度(项目数)。参数可以是序列(例如字符串,字节,元组,列表或范围)或集合(例如字典,集合或冻结集合)。

len是通过数据模型docs 中的 __len__实现的:

object.__len__(self)

调用以实现内置函数len() 。应该返回对象的长度,即 > = 0 的整数。此外,考虑未定义__nonzero__() [在 Python 2 中为__bool__()在 Python 3 中] 且其__len__()方法返回零的对象。在布尔上下文中为 false。

我们还可以看到__len__是列表的方法:

items.__len__()

返回 3。

内建类型可以得到len (长度)

实际上,我们看到我们可以为所有描述的类型获取此信息:

>>> all(hasattr(cls, '__len__') for cls in (str, bytes, tuple, list, 
                                            xrange, dict, set, frozenset))
True

请勿使用len测试空列表或非空列表

当然,要测试特定长度,只需测试是否相等:

if len(items) == required_length:
    ...

但是在测试零长度列表或反数列表时有一种特殊情况。在这种情况下,请勿测试是否相等。

另外,请勿执行以下操作:

if len(items): 
    ...

相反,只需执行以下操作:

if items:     # Then we have some items, not empty!
    ...

要么

if not items: # Then we have an empty list!
    ...

在这里解释原因,但简而言之,无论是if items还是if not items都更具可读性和性能。

尽管由于 “开箱即用” 功能在意义上更有意义,所以这可能没有用,但是一个相当简单的技巧是用length属性构建一个类:

class slist(list):
    @property
    def length(self):
        return len(self)

您可以这样使用它:

>>> l = slist(range(10))
>>> l.length
10
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

本质上,它与列表对象完全相同,其附加好处是具有友好的 OOP length属性。

和往常一样,您的里程可能会有所不同。

除了len之外,您还可以使用operator.length_hint (需要 Python 3.4+)。对于普通list两者都是等效的,但是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__方法总是更安全!

通过前面给出的示例来回答您的问题:

items = []
items.append("apple")
items.append("orange")
items.append("banana")

print items.__len__()

为了完整(主要是教育性的),可以不使用len()函数。我不认为这是一个很好的选择。 不要像在 PYTHON 中那样编程 ,但这是学习算法的目的。

def count(list):
    item_count = 0
    for item in list[:]:
        item_count += 1
    return item_count

count([1,2,3,4,5])

list[:]的冒号是隐式的,因此也是可选的。)

对于新程序员来说,这里的课程是:您无法在不计算数量的情况下获得列表中的项目数。问题就变成了:什么时候该计数它们呢?例如,诸如套接字的连接系统调用之类的高性能代码(用 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()实际工作方式,这是其 C 实现

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;
    }
    return PyLong_FromSsize_t(res);
}

Py_ssize_t是对象可以具有的最大长度。 PyObject_Size()是一个返回对象大小的函数。如果无法确定对象的大小,则返回 - 1。在这种情况下,将执行以下代码块:

if (res < 0) {
        assert(PyErr_Occurred());
        return NULL;
    }

结果引发了异常。否则,将执行以下代码块:

return PyLong_FromSsize_t(res);

resC整数,将其转换为 python long并返回。自 Python 3 起,所有 python 整数都存储为longs