Эффективный способ транслировать / перебирать значения словаря - PullRequest
1 голос
/ 16 февраля 2020

Я пытаюсь использовать значения словаря в вычислениях, таких как:

mydict = dict(zip(['key1', 'key2', 'key3'],
                  [1, 2, 3]))
print(mydict)

newvals = (mydict.values() + 3) ** 2
print(newvals)
{'key1': 1, 'key2': 2, 'key3': 3}
TypeError: unsupported operand type(s) for +: 'dict_values' and 'int'

Или, если я это сделаю,

import numpy as np
newvals = (np.array(mydict.values()) + 3) ** 2
print(newvals)
TypeError: unsupported operand type(s) for +: 'dict_values' and 'int'

Кажется, я должен сначала преобразуйте значения словаря в список, или итерируйте с пониманием списка.

newvals = (np.array(list(mydict.values())) + 3) ** 2
print(newvals)
[16 25 36]

Или я могу сделать

newvals = np.array([(val + 3) ** 2 for val in mydict.values()])
print(newvals)
[16 25 36]

Есть ли проще или больше эффективный способ сделать это? Или есть встроенный метод для словарей, который я могу использовать, чтобы мне не приходилось пользоваться списком или для l oop?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 16 февраля 2020

Когда мы говорим об избежании циклов в numpy, мы на самом деле имеем в виду избегание циклов Python. Нам по-прежнему нужно l oop через элементы массива, но мы делаем это в быстром скомпилированном коде. Этот код работает только на numpy ndarrays. Кроме того, циклы через массивы хуже, чем циклы, хотя списки.

Если мы начнем со списков, мы должны сначала преобразовать его в ndarray, например arr = np.array([1,2,3]). Преобразование массива требует времени, достаточно того, что часто быстрее понять список.

numpy не имеет кода для прямой работы с Python dicts. values() делает объект, похожий на генератор. np.array(...) требуется список, подобный объекту:

In [140]: np.array(list(mydict.values()))                                                      
Out[140]: array([1, 2, 3])
In [141]: (np.array(list(mydict.values())) +3)**2                                              
Out[141]: array([16, 25, 36])

fromiter может работать с объектом values:

In [142]: np.fromiter(mydict.values(), int)                                                    
Out[142]: array([1, 2, 3])

np.fromiter может быть быстрее, чем np.array, но я не гарантирую это.

Я подозреваю, что понимание списка быстрее, особенно для этого небольшого примера:

In [143]: [(x+3)**2 for x in mydict.values()]                                                  
Out[143]: [16, 25, 36]

Мы могли бы провести некоторое время тестирования, но для этого небольшого образца это, вероятно, не будет таким полезным.

Словари полезны для многих вещей, но быстрые вычисления чисел c - это не одно из них.

1 голос
/ 16 февраля 2020

Это должно решить это за вас.

for key, value in mydict.items():
    mydict[key] = (value + 3) ** 2
0 голосов
/ 16 февраля 2020
    for([key,value] in mydict.items()){

      mydict[key] = (value + 3 ) ** 2

      console.log(mydict[key]);

     }

Таким образом, вы получаете доступ к e. g 1 касаясь «key1». 1 + 3 ** 2. первое значение от ключа 1: 16

...