Лучший способ (с точки зрения производительности) перебирать словарь - PullRequest
0 голосов
/ 04 октября 2019

Это говорит о том, что .items() - лучший способ перебора словаря, потому что он питонический.

Что касается производительности, какой из перечисленных ниже является лучшим и почему?

  1. for key in dic:
        value = dic[key]
    
  2. for key, value in dic.items():
    
  3. for key in dic.keys():
        value = dic[key]
    

Ответы [ 4 ]

2 голосов
/ 04 октября 2019

На основе значений времени:

Чтобы найти ключи и значения,

from timeit import timeit

d = {i: i for i in range(100)}

def a():
    for key in d:
        d[key]
        pass

def b():
    for key, value in d.items():
        pass

def c():
    for key in d.keys():
        d[key]
        pass

for fn in [a, b, c]:
    print(fn.__name__, timeit(fn))


Solution 1 7.8113735559999995
Solution 2 2.6758934780000008
Solution 3 5.499667492

Чтобы просто найти ключи,

from timeit import timeit

d = {i: i for i in range(100)}

def a():
    for key in d:
        pass

def b():
    for key, value in d.items():
        pass

def c():
    for key in d.keys():
        pass

for fn in [a, b, c]:
    print(fn.__name__, timeit(fn))

Solution 1 1.5981329149999999
Solution 2 2.649033456
Solution 3 1.6517934609999996

Таким образом, чтобы найти ключиПервое решение является самым быстрым, но для поиска ключей и ценностей второе решение является самым быстрым.

1 голос
/ 04 октября 2019

Такого рода общие тайминги редко бывают полезны, поскольку производительность определяется гораздо более широким набором переменных, специфичных для данных, приложения и среды, о которых идет речь, но для предоставления простых данных сравнения приведем несколько тестов, которые выможно копировать и пробовать в вашей собственной среде.

Простая итерация без доступа к значениям dict Не удивительно, что разница между производительностью очень мала, за исключением того, что dict.items() работает немного позади, поскольку создает представление. обоих ключей и значений (в то время как другие показанные методы имеют дело только с одним или другим).

from timeit import timeit

loop = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d: pass"""
print(timeit(stmt=loop, number=10000))
# 1.0733639170002789

keys = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d.keys(): pass"""
print(timeit(stmt=keys, number=10000))
# 1.0360493710004448

values = """
d = dict(zip(range(1000), reversed(range(1000))))
for v in d.values(): pass"""
print(timeit(stmt=values, number=10000))
# 1.0380961279997791

items = """
d = dict(zip(range(1000), reversed(range(1000))))
for v in d.items(): pass"""
print(timeit(stmt=items, number=10000))
# 1.2011308679993817

Повторение при доступе к значению для каждого ключа в попытке выровнять игровое поле неудивительно, что dict.items() немного быстрее, когда вам нужно выполнить итерацию и получить доступ к ключам и значениям.

from timeit import timeit

loop = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d: d[k]"""
print(timeit(stmt=loop, number=10000))
# 1.4128917540001567

keys = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d.keys(): d[k]"""
print(timeit(stmt=keys, number=10000))
# 1.3668724469998779

items = """
d = dict(zip(range(1000), reversed(range(1000))))
for v in d.items(): pass"""
print(timeit(stmt=items, number=10000))
# 1.1864945030001763
1 голос
/ 04 октября 2019

Если вам нужны и ключи, и значения, используйте for k, v in mydict.items():;итерация ключей и их поиск означает ненужный поиск информации, которую вы могли бы получить бесплатно с помощью .items(). Для очень коротких dict с он может быть медленнее, чем for k in mydict: с последующим поиском (просто потому, что создание представления элементов очень мало, может превышать таковое для нескольких поисков), нодля dict с умеренной длины .items() всегда будет выигрывать.

Если вам нужны только ключи, оба for k in mydict: и for k in mydict.keys(): примерно одинаковы, хотя последний немного медленнее вPy3 (из-за необходимости построения представления ключей) и может быть значительно медленнее на Py2 (где он создает временную list с копией ключей, где прежний подход лениво выполняет итерацию dict напрямую).

0 голосов
/ 04 октября 2019

Два - ваш лучший вариант по двум причинам:

1) Вы можете получить и ключ, и значение, поэтому вы экономите ресурсы при повторном вызове, когда захотите

2) Как вы сказали, это «pythonic» и это самый быстрый метод там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...