Відповіді:
Це O (1) (постійний час, не залежно від фактичної довжини елемента - дуже швидко) для кожного згаданих вами типів, а також set
інших тощо array.array
.
Виклик len () для цих типів даних є O (1) в CPython , найпоширеніша реалізація мови Python. Ось посилання на таблицю, яка забезпечує алгоритмічну складність багатьох різних функцій у CPython:
Усі ці об’єкти відстежують власну довжину. Час вилучення довжини невеликий (O (1) в нотації big-O) і здебільшого складається з [грубого опису, написаного термінами Python, а не з термінами C]: шукайте "len" у словнику та відправляйте його до вбудована функція len, яка шукатиме __len__
метод об'єкта і викликає, що ... все, що він повинен зробити, - цеreturn self.length
length
з’являється у словнику від dir(list)
?
list.lenght
змінна реалізована в C, а не в Python.
Наведені нижче вимірювання забезпечують доказ того, що len()
O (1) для часто використовуваних структур даних.
Примітка щодо timeit
: Коли використовується -s
прапор і два рядки передаються timeit
в перший рядок, виконується лише один раз і не приурочено до часу.
$ python -m timeit -s "l = range(10);" "len(l)"
10000000 loops, best of 3: 0.0677 usec per loop
$ python -m timeit -s "l = range(1000000);" "len(l)"
10000000 loops, best of 3: 0.0688 usec per loop
$ python -m timeit -s "t = (1,)*10;" "len(t)"
10000000 loops, best of 3: 0.0712 usec per loop
$ python -m timeit -s "t = (1,)*1000000;" "len(t)"
10000000 loops, best of 3: 0.0699 usec per loop
$ python -m timeit -s "s = '1'*10;" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -m timeit -s "s = '1'*1000000;" "len(s)"
10000000 loops, best of 3: 0.0686 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(10))};" "len(d)"
10000000 loops, best of 3: 0.0711 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(1000000))};" "len(d)"
10000000 loops, best of 3: 0.0727 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(10));" "len(a)"
10000000 loops, best of 3: 0.0682 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(1000000));" "len(a)"
10000000 loops, best of 3: 0.0753 usec per loop
$ python -mtimeit -s"s = {i for i in range(10)};" "len(s)"
10000000 loops, best of 3: 0.0754 usec per loop
$ python -mtimeit -s"s = {i for i in range(1000000)};" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(10));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(1000000));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
len()
, а також зафіксував вимірювання, щоб правильно використовувати -s
прапор.
python -m timeit -s "l = range(10000);" "len(l); len(l); len(l)"
223 нсек за цикл python -m timeit -s "l = range(100);" "len(l)"
66,2 нсек за цикл
len - це O (1), оскільки у вашій ОЗУ списки зберігаються у вигляді таблиць (серія суміжних адрес). Щоб знати, коли таблиця зупиняється, комп'ютер потребує двох речей: довжина та початкова точка. Ось чому len () - це O (1), комп'ютер зберігає значення, тому його просто потрібно шукати.
Я думав, що len () в Python залежить від розміру списку, тому я завжди зберігаю довжину в змінній, якщо використовую кілька разів. Але сьогодні під час налагодження я помітив атрибут __len__ у об’єкті списку, тому len () повинен бути лише його видобуванням, що робить складність O (1). Тож я просто гуглив, якщо хтось це вже запитав і натрапив на цю посаду.
__len__
це функція, а не змінна, яка представляє довжину списку.
list.__len__
функція працює в постійний час? Це робить, але не лише тому, що це функція. Тому що він реалізований так.