Обратите внимание на следующее:

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

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

Как я могу получить количество элементов в списке items?

2099
y2k 11 Ноя 2009 в 03:30

7 ответов

Лучший ответ

Функция len() может использоваться с несколькими различными типами в Python - как встроенными типами, так и типами библиотек. Например:

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

Официальная документация 2.x находится здесь: {{X0} }
Официальная документация 3.x находится здесь: {{X1} }

2731
Boris 12 Янв 2021 в 17:00

С точки зрения того, как 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 целым числом, конвертируется в питон long и возвращается. Все целые числа Python хранятся как longs, начиная с Python 3.

0
Boris 12 Янв 2021 в 17:11

А для полноты (в основном образовательной) это возможно без использования функции len(). Я не одобрил бы это как хороший вариант НЕ ПРОГРАММИРОВАТЬ, КАК ЭТО В ПИТОНЕ , но он служит цели для изучения алгоритмов.

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

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

(Двоеточие в list[:] неявно и поэтому также необязательно.)

Здесь урок для новых программистов: вы не можете получить количество элементов в списке, не посчитав их в какой-то момент. Возникает вопрос: когда самое время их считать? Например, высокопроизводительный код, такой как системный вызов connect для сокетов (написанный на C) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, не вычисляет длину элементов (возлагая эту ответственность на вызывающий код). Обратите внимание, что длина адреса передается, чтобы сохранить шаг подсчета длины в первую очередь? Другой вариант: в вычислительном отношении может иметь смысл отслеживать количество элементов по мере их добавления в передаваемый объект. Имейте в виду, что это занимает больше места в памяти. См. ответ Нафтули Кея.

Пример отслеживания длины для улучшения производительности, занимая больше места в памяти. Обратите внимание, что я никогда не использую функцию 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
7
Jonathan Komar 8 Ноя 2019 в 12:55

Отвечая на ваш вопрос в качестве примеров, также приведенных ранее:

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

print items.__len__()
8
Peter Mortensen 27 Май 2017 в 22:03

Помимо 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, но это может привести к проблемам с пользовательскими классами, потому что lenlength_hint) реализуют некоторые проверки безопасности. Например, оба не допускают отрицательных длин или длин, которые превышают определенное значение (значение sys.maxsize). Поэтому всегда безопаснее использовать функцию len вместо метода __len__!

20
Peter Mortensen 17 Мар 2019 в 09:14

Хотя это может быть бесполезно из-за того факта, что было бы гораздо более разумно использовать функциональность «из коробки», довольно простым способом было бы создать класс со свойством 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]

По сути, он в точности идентичен объекту списка с дополнительным преимуществом наличия свойства length OOP-friendly.

Как всегда, ваш пробег может отличаться.

74
Naftuli Kay 19 Апр 2013 в 21:51

Как получить размер списка?

Чтобы найти размер списка, используйте встроенную функцию len:

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

И сейчас:

len(items)

Возвращает 3.

Объяснение

Все в Python является объектом, включая списки. Все объекты имеют какой-то заголовок в C-реализации.

Списки и другие подобные встроенные объекты с «размером» в Python, в частности, имеют атрибут ob_size, в котором кэшируется количество элементов в объекте. Поэтому проверка количества объектов в списке выполняется очень быстро.

Но если вы проверяете, равен ли размер списка нулю или нет, не используйте len - вместо этого поместите список в логический контекст - он считается ложным, если пустой, истинным в противном случае.

Из документов.

< Сильный > len(s)

Возвращает длину (количество элементов) объекта. Аргументом может быть последовательность (например, строка, байты, кортеж, список или диапазон) или коллекция (например, словарь, набор или замороженный набор).

len реализован с помощью __len__ из модели данных docs. :

< Сильный > object.__len__(self)

Вызывается для реализации встроенной функции len(). Должен возвращать длину объекта, целое число> = 0. Кроме того, объект, который не определить метод __nonzero__() [в Python 2 или __bool__() в Python 3], и чей метод __len__() возвращает ноль считается ложным в логическом контексте.

И мы также можем видеть, что __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 более удобочитаемы и более производительны.

249
Aaron Hall 7 Июл 2018 в 14:33