отличие [*dict.keys()] от list(dict.keys())

Есть ли разница между этими выражениями?

[*dict.keys()] от list(dict.keys())


Ответы (1 шт):

Автор решения: CrazyElf

По результату разницы нет. А вот по тому, как оно выглядит внутри, разница есть. Сделаем две функции с этими реализациями:

def func1(d):
    return [*d.keys()]

def func2(d):
    return list(d.keys())

Посмотрим, что там внутри:

import dis

dis.dis(func1)
print()
dis.dis(func2)

Вывод:

  4           0 LOAD_FAST                0 (d)
              2 LOAD_METHOD              0 (keys)
              4 CALL_METHOD              0
              6 BUILD_LIST_UNPACK        1
              8 RETURN_VALUE

  7           0 LOAD_GLOBAL              0 (list)
              2 LOAD_FAST                0 (d)
              4 LOAD_METHOD              1 (keys)
              6 CALL_METHOD              0
              8 CALL_FUNCTION            1
             10 RETURN_VALUE

Как видно в первом варианте вызывается встроенный метод BUILD_LIST_UNPACK, а во втором ищется и вызывается функция list. Подозреваю, что второе должно быть медленнее. Проверим:

from timeit import timeit
import seaborn as sns

n = 8
a = []
b = []
for i in range(n):
    r = range(2**i)
    d = dict(zip(r, r))
    a.append(timeit(lambda: func1(d)))
    b.append(timeit(lambda: func2(d)))
    
sns.lineplot(x=range(n), y=a, label='[*d.keys()]');
sns.lineplot(x=range(n), y=b, label='list(d.keys())');

введите сюда описание изображения

С ростом размера словаря скорость падает, абсолютная разница времени выполнения остаётся примерно та же, но она всё менее заметна на фоне общего времени выполнения:

введите сюда описание изображения

→ Ссылка