Я работаю с довольно большим количеством значений в Python (объем памяти составляет 5 ГБ).
Иногда мне нужно получить доступ к значениям по ключу, иногда мне нужно зациклить значения.Из соображений производительности при запуске я конвертирую Dict в список, поэтому я могу:
- использовать Dict в тех случаях, когда я хочу получить доступ к значениям по ключу
- , использовать списокв случаях, когда я хочу зациклить значения
my_big_dict_of_values
my_big_values_list = list(my_big_dict_of_values.values())
Вот сравнение производительности, просто для ясности:
>some_dict = dict(zip(range(1000000), reversed(range(1000000))))
>some_list = list(some_dict.values())
>%timeit for t in some_dict.values(): t
21.1 ms ± 483 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
>%timeit for t in some_list: t
16.1 ms ± 1.31 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
Моя проблема возникает, когда мне нужноудалить ключи из dict на основе ввода пользователя.Сначала я удаляю записи из dict с помощью:
for key in keys_to_remove:
del(my_big_dict_of_values[key])
После этой операции я также хочу обновить my_big_values_list
.Я могу сделать это с помощью:
Решение A (Медленно)
indexes_to_remove = list()
for idx, value in enumerate(my_big_values_list):
if value.key in keys_to_remove:
indexes_to_remove.append(idx)
for index in sorted(indexes_to_remove, reverse=True):
del my_big_values_list[index]
Однако, это действительно медленно и громоздко.
В идеале, яхотел бы просто снова создать список из dict с помощью:
Решение B (Быстро с проблемой ссылки)
my_big_values_list = list(my_big_dict_of_values.values())
Это быстро, но, похоже,создать новую ссылку.Мне нужно будет заменить все ссылки my_big_values_list
, переданные другим классам / функциям, что выглядит странно, например, для иллюстрации.
my_big_dict_of_values
my_big_values_list = list(
my_big_dict_of_values.values())
handle_process = handle_process_class(
my_big_dict_of_values, my_big_values_list)
userinput = userinput(handle_process)
handle_process.calculate()
def userinput_class():
def __init__(handle_process):
self.handle_process = handle_process
def user_del_key(key):
del(self.handle_process.my_big_dict_of_values[key])
# Update list here too:
# Solution A works
# Solution B throws error in
# handle_process.calculate() because
# handle_process still has old list
def handle_process_class():
def __init__(my_big_dict_of_values, my_big_values_list):
self.my_big_dict_of_values = my_big_dict_of_values
self.my_big_values_list = my_big_values_list
def calculate(self):
return len(self.my_big_values_list)
Есть ли способ изменить my_big_values_list
на месте, но просто заменитьс новым списком (например, list (my_big_dict_of_values.values ())).
Я прочитал, как Python передает ссылки на значения, и я думаю, что понимаю большинство из них.Вот почему я придумал решение A, но я не знаю, как использовать Решение B для изменения ссылочного списка.Возможно, кто-то может объяснить, что здесь происходит?