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

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

考虑以下:

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

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

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

Consider the following:

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

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

How do I get the number of elements in the list items?


回答 0

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

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

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

The len() function can be used with several different types in Python – both built-in types and library types. For example:

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

Official 2.x documentation is here: len()
Official 3.x documentation is here: len()


回答 1

如何获得列表的大小?

要查找列表的大小,请使用内置函数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与实施__len__,从数据模型文档

object.__len__(self)

调用以实现内置函数len()。应该返回对象的长度,即> = 0的整数。而且,在Boolean上下文中,未定义__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更具可读性和性能。

How to get the size of a list?

To find the size of a list, use the builtin function, len:

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

And now:

len(items)

returns 3.

Explanation

Everything in Python is an object, including lists. All objects have a header of some sort in the C implementation.

Lists and other similar builtin objects with a “size” in Python, in particular, have an attribute called ob_size, where the number of elements in the object is cached. So checking the number of objects in a list is very fast.

But if you’re checking if list size is zero or not, don’t use len – instead, put the list in a boolean context – it treated as False if empty, True otherwise.

From the docs

len(s)

Return the length (the number of items) of an object. The argument may be a sequence (such as a string, bytes, tuple, list, or range) or a collection (such as a dictionary, set, or frozen set).

len is implemented with __len__, from the data model docs:

object.__len__(self)

Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn’t define a __nonzero__() [in Python 2 or __bool__() in Python 3] method and whose __len__() method returns zero is considered to be false in a Boolean context.

And we can also see that __len__ is a method of lists:

items.__len__()

returns 3.

Builtin types you can get the len (length) of

And in fact we see we can get this information for all of the described types:

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

Do not use len to test for an empty or nonempty list

To test for a specific length, of course, simply test for equality:

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

But there’s a special case for testing for a zero length list or the inverse. In that case, do not test for equality.

Also, do not do:

if len(items): 
    ...

Instead, simply do:

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

or

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

I explain why here but in short, if items or if not items is both more readable and more performant.


回答 2

虽然由于“开箱即用”功能在意义上更有意义,所以这可能没有用,但是一个相当简单的技巧是使用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属性。

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

While this may not be useful due to the fact that it’d make a lot more sense as being “out of the box” functionality, a fairly simple hack would be to build a class with a length property:

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

You can use it like so:

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

Essentially, it’s exactly identical to a list object, with the added benefit of having an OOP-friendly length property.

As always, your mileage may vary.


回答 3

此外,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__方法总是更安全!

Besides len you can also use operator.length_hint (requires Python 3.4+). For a normal list both are equivalent, but length_hint makes it possible to get the length of a list-iterator, which could be useful in certain circumstances:

>>> 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

But length_hint is by definition only a “hint”, so most of the time len is better.

I’ve seen several answers suggesting accessing __len__. This is all right when dealing with built-in classes like list, but it could lead to problems with custom classes, because len (and length_hint) implement some safety checks. For example, both do not allow negative lengths or lengths that exceed a certain value (the sys.maxsize value). So it’s always safer to use the len function instead of the __len__ method!


回答 4

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

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

print items.__len__()

Answering your question as the examples also given previously:

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

print items.__len__()

回答 5

并且为了完整性(主要是教育性的),可以不使用该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

And for completeness (primarily educational), it is possible without using the len() function. I would not condone this as a good option DO NOT PROGRAM LIKE THIS IN PYTHON, but it serves a purpose for learning algorithms.

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

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

(The colon in list[:] is implicit and is therefore also optional.)

The lesson here for new programmers is: You can’t get the number of items in a list without counting them at some point. The question becomes: when is a good time to count them? For example, high-performance code like the connect system call for sockets (written in C) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, does not calculate the length of elements (giving that responsibility to the calling code). Notice that the length of the address is passed along to save the step of counting the length first? Another option: computationally, it might make sense to keep track of the number of items as you add them within the object that you pass. Mind that this takes up more space in memory. See Naftuli Kay‘s answer.

Example of keeping track of the length to improve performance while taking up more space in memory. Note that I never use the len() function because the length is tracked:

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

回答 6

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);

res这是一个C整数,将转换为python long并返回。longs自python 3起,所有python整数都存储。

In terms of how len() actually works, this is its C implementation:

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 is the maximum length that the object can have. PyObject_Size() is a function that returns the size of an object. If it cannot determine the size of an object, it returns -1. In that case, this code block will be executed:

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

And an exception is raised as a result. Otherwise, this code block will be executed:

return PyLong_FromSsize_t(res);

res which is a C integer, is converted into a python long and returned. All python integers are stored as longs since Python 3.