Python:在引用列表的位置替换列表,而不是创建新的引用/列表

Python:在引用列表的位置替换列表,而不是创建新的引用/列表,python,performance,reference,pass-by-value,Python,Performance,Reference,Pass By Value,我在Python中处理大量的值(内存占用是5GB) 有时,我需要通过键访问值,有时我需要循环值。出于性能原因,我在启动时将Dict转换为列表,以便: 如果我希望通过键访问值,请使用Dict 在需要循环值的情况下使用该列表 my_big_dict__值 my_big_values_list=list(my_big_dict_of_values.values()) 为了清楚起见,这里有一个性能比较: >some_dict=dict(zip(范围(1000000)),reversed(范围(10

我在Python中处理大量的值(内存占用是5GB)

有时,我需要通过键访问值,有时我需要循环值。出于性能原因,我在启动时将Dict转换为列表,以便:

  • 如果我希望通过键访问值,请使用Dict
  • 在需要循环值的情况下使用该列表
my_big_dict__值
my_big_values_list=list(my_big_dict_of_values.values())
为了清楚起见,这里有一个性能比较:

>some_dict=dict(zip(范围(1000000)),reversed(范围(1000000)))
>some_list=list(some_dict.values())
>%在某些默认值()中为t计时:t
每个回路21.1 ms±483µs(7次运行的平均值±标准偏差,每个10个回路)
>%某些列表中t的时间:t
每个回路16.1 ms±1.31 ms(7次运行的平均值±标准偏差,每个100个回路)
当我需要根据用户输入从dict中删除密钥时,问题就出现了。 首先,我使用以下命令从dict中删除条目:

对于要删除的钥匙插入:
del(我的大数值[key])
完成此操作后,我还想更新
我的\u big\u values\u列表
。我可以这样做:

解决方案A(慢速)

index\u to\u remove=list()
对于idx,枚举中的值(我的大值列表):
如果value.key输入要删除的键:
索引\u到\u删除.追加(idx)
对于排序中的索引(索引从\u到\u删除,反向=True):
删除我的大值列表[索引]
然而,这是非常缓慢和繁琐的

理想情况下,我只想再次从dict中创建列表,其中包括:

解决方案B(带参考问题的Fast)

my\u big\u values\u list=list(my\u big\u dict\u of\u values.values())
这很快,但似乎创建了一个新的引用。我需要替换传递给其他类/函数的
my_big\u values\u list
的所有引用,这看起来很奇怪,例如为了说明

my_big_dict__值
我的\u大\u值\u列表=列表(
我的\u big\u dict\u of \u values.values())
handle\u process=handle\u process\u类(
我的价值观清单、我的价值观清单)
userinput=userinput(处理进程)
handle_process.calculate()
def userinput_class():
定义初始化(句柄进程):
self.handle\u进程=handle\u进程
def用户删除键(键):
del(self.handle\u process.my\u big\u dict\u of\u values[key])
#请在此更新列表:
#解决方案A有效
#解决方案B抛出错误
#handle_process.calculate()是因为
#handle\u进程仍有旧列表
def handle_process_class():
定义初始值(我的大值目录,我的大值列表):
self.my\u big\u dict\u of值=my\u big\u dict\u of值
self.my\u big\u values\u list=my\u big\u values\u list
def计算(自我):
return len(self.my\u big\u values\u列表)
是否有一种方法可以就地修改
my_big_values_list
,但只需替换为一个新列表(例如,list(my_big_dict_of_values.values())


我读过Python如何传递对值的引用,我想我理解了其中的大部分内容。这就是为什么我提出了解决方案A,但我不知道如何使用解决方案B来修改引用的列表。也许有人可以解释一下这里发生了什么?

要修改列表,请将以下内容分配给其切片:

my_big_values_list[:] = list(my_big_dict_of_values.values())
例如:

>>> my_big_dict_of_values = {"a": 1, "b": 2, "c": 3}
>>> my_big_values_list = list(my_big_dict_of_values.values())
>>> another_list_reference = my_big_values_list

>>> print(my_big_values_list, another_list_reference)
[1, 2, 3] [1, 2, 3]

>>> del(my_big_dict_of_values["b"])
>>> my_big_values_list[:] = list(my_big_dict_of_values.values())

>>> print(my_big_values_list, another_list_reference)
[1, 3] [1, 3]

但是,在性能和内存使用方面,您应该考虑是否需要一个单独的大列表,因为您可以直接在<代码>字典> Values()> />代码> ./P> < P>中修改列表,将其分配给其切片:

my_big_values_list[:] = list(my_big_dict_of_values.values())
例如:

>>> my_big_dict_of_values = {"a": 1, "b": 2, "c": 3}
>>> my_big_values_list = list(my_big_dict_of_values.values())
>>> another_list_reference = my_big_values_list

>>> print(my_big_values_list, another_list_reference)
[1, 2, 3] [1, 2, 3]

>>> del(my_big_dict_of_values["b"])
>>> my_big_values_list[:] = list(my_big_dict_of_values.values())

>>> print(my_big_values_list, another_list_reference)
[1, 3] [1, 3]

然而,在性能和内存使用方面,您应该考虑是否需要一个单独的大列表,因为您可以直接在DistabySe()/<代码>上循环。在yourdict.values()中循环值就像

for val一样简单:
或者-如果您使用的是Python 2.7并且希望在yourdict.iter\u values()中为val保存RAM-
我同意大多数情况,但是在列表上迭代要比在dict.values()上迭代要多,这在我的dict()中的值的数量上是显而易见的注意:我编辑了我的原始答案,并添加了一个性能比较单元,它本身可能更快,但维护列表的开销也会增加一些开销,因此根据具体的用例,净收益可能会很重要,也可能没有那么重要(真的说不出来)。此外,这也可能不是代码中的主要瓶颈,因此如果您想正确优化代码,您确实需要首先对其进行分析。(注意:并不是说当前的优化是无用的或没有意义的——只是我们人类在猜测任何非平凡代码中真正的瓶颈在哪里方面非常糟糕。)完全同意:我可能需要正确地测试代码的性能。更详细的背景:my_big_dict_of_values是我程序的核心,我在它上面的代码的所有部分都运行了数百万次迭代。你确定你需要这个列表吗???在yourdict.values()中循环值就像
for val一样简单:
或者-如果您使用的是Python 2.7并且希望在yourdict.iter\u values()中为val保存RAM-
我同意大多数情况,但是在列表上迭代要比在dict.values()上迭代要多,这在我的dict()中的值的数量上是显而易见的注意:我编辑了我的原始答案,并添加了一个性能比较单元,它本身可能更快,但维护列表的开销也会增加一些开销,因此根据具体的用例,净收益可能会很重要,也可能没有那么重要(真的说不出来)。此外,这也可能不是代码中的主要瓶颈,因此如果您想正确优化代码,您确实需要首先对其进行分析。(注:这并不是说当前的优化是无用的或没有意义的——只是我们人类在猜测w方面非常糟糕