Как быстро обновить большой словарь, используя список? - PullRequest
2 голосов
/ 24 июня 2019

Я ищу быстрый способ обновления значений в (упорядоченном) словаре, который содержит десятки миллионов значений, где обновленные значения хранятся в списке / массиве.

Программа, которую я пишу, берет список ключей из исходного словаря (которые являются числовыми кортежами) в виде массива-пустышки и передает их через функцию, которая возвращает массив новых чисел (по одному для каждого значения ключа).).Затем этот массив умножается на соответствующие значения словаря (посредством пошагового умножения массива), и именно этот возвращаемый одномерный массив значений мы хотим использовать для обновления словаря.Записи в новом массиве хранятся в порядке соответствующих ключей, поэтому я мог бы использовать цикл, чтобы пройти по словарю и обновить значения одно за другим.Но это слишком неэффективно.Есть ли более быстрый способ обновления значений в этом словаре, который не использует циклы?

Примером подобной проблемы может быть, если ключи в словаре представляют координаты x и y точекв пространстве, а значения представляют силы, прилагаемые в этой точке.Если мы хотим вычислить крутящий момент, испытываемый в каждой точке от начала координат, нам сначала понадобится функция, подобная:

def euclid(xy):
   return (xy[0]**2 + xy[1]**2)**0.5

, которая, если xy представляет x, y-кортеж, вернет евклидовурасстояние от начала координатЗатем мы могли бы умножить это на соответствующее значение словаря, чтобы вернуть крутящий момент, например так:

for xy in dict.keys():
   dict[xy] = euclid(xy)*dict[xy]

Но этот цикл медленный, и мы могли бы воспользоваться алгеброй массива, чтобы получить новые значения в одной операции:

new_dict_values = euclid(np.array(dict.keys()))*np.array(dict.values())

И именно здесь мы хотим найти быстрый способ обновления словаря вместо использования:

i = 0
for key in dict.keys():
    dict[key] = new_dict_value[i]
    i += 1

1 Ответ

3 голосов
/ 24 июня 2019

Последний кусок кода не просто медленный.Я не думаю, что он делает то, что вы хотите, чтобы он делал:

for key in dict.keys():
    for i in range(len(new_dict_values)):
        dict[key] = new_dict_value[i]

Для каждого ключа в словаре вы перебираете весь список new_dict_values ​​и присваиваете каждому значение этого ключа,перезаписать значение, которое вы присвоили в предыдущей итерации циклаЭто даст вам словарь, в котором каждый ключ имеет значение последнего элемента в new_dict_value, что я не думаю, что вы хотите.

Если вы уверены, что порядок ключей в словаретак же, как порядок значений в new_dict_values, вы можете сделать это:

for key, value in zip(dict.keys(), new_dict_values):
    dict[key] = value

Редактировать: Кроме того, в будущем нет необходимости в Python для перебора диапазона чисел и доступа к элементамсписок через индекс.Это:

for i in range(len(new_dict_values)):
        dict[key] = new_dict_value[i]

эквивалентно этому:

for i in new_dict_values:
        dict[key] = i
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...