Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何在整个赋值过程中保持可变内存位置?_Python_Memory_Variables_Fftw - Fatal编程技术网

Python:如何在整个赋值过程中保持可变内存位置?

Python:如何在整个赋值过程中保持可变内存位置?,python,memory,variables,fftw,Python,Memory,Variables,Fftw,我对Python还是相当陌生,所以如果这个问题很愚蠢,请原谅我。我无法通过谷歌找到答案 我在我的代码中使用PyFFTW,它有一个计划阶段,在这个阶段中,您向它传递两个变量(源/目标),您的转换从/到。然后,当您调用FFT时,它将对精确的内存空间进行操作,这些变量在规划阶段位于该内存空间。因此,需要对变量执行任何操作,以便这两个变量在内存中的位置不会改变。 我找到了运算符*=,+=等,它们对标准数学运算符执行此操作。 然而,在我的程序中,我需要对变量应用一个函数,它应该将变量返回到相同的内存位置。

我对Python还是相当陌生,所以如果这个问题很愚蠢,请原谅我。我无法通过谷歌找到答案

我在我的代码中使用PyFFTW,它有一个计划阶段,在这个阶段中,您向它传递两个变量(源/目标),您的转换从/到。然后,当您调用FFT时,它将对精确的内存空间进行操作,这些变量在规划阶段位于该内存空间。因此,需要对变量执行任何操作,以便这两个变量在内存中的位置不会改变。 我找到了运算符
*=
+=
等,它们对标准数学运算符执行此操作。 然而,在我的程序中,我需要对变量应用一个函数,它应该将变量返回到相同的内存位置。 怎么做

我最初使用切片的方式如下:

a[:] = func(a)[:]
然而,我刚刚意识到,这是非常慢的(我的代码大约慢10%)。 有人知道怎么做吗


非常感谢您的帮助。提前谢谢

您的变量是可变类型,因此您的函数可以直接对其进行操作


您仍然无法使用将创建副本和/或进行新赋值的函数和运算符(与您无法使用的相同),但函数参数的直接突变将在函数外部可见。

您的变量是可变类型,因此您的函数可以直接对其进行操作


您仍然无法使用将创建副本和/或进行新赋值的函数和运算符(与您无法使用的相同),但函数参数的直接突变将在函数外部可见。

这是您正在尝试的吗

def time10(a):
  """ multiple the elements by 10 in-place """
  for i in xrange(len(a)):
    a[i] *= 10
  # returning a is optional. I think it maybe useful for use to chain the operation
  return a

>>> a = range(10)
>>> time10(a)
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> b = range(10)
>>> time10(time10(b))
[0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
>>> b
[0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
>>>

原始代码在数组返回后复制数组。这通常不是一个有用的实践,并且会导致运行速度变慢。

这是您正在尝试做的事情吗

def time10(a):
  """ multiple the elements by 10 in-place """
  for i in xrange(len(a)):
    a[i] *= 10
  # returning a is optional. I think it maybe useful for use to chain the operation
  return a

>>> a = range(10)
>>> time10(a)
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> b = range(10)
>>> time10(time10(b))
[0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
>>> b
[0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
>>>

原始代码在数组返回后复制数组。这通常不是一种有用的做法,会导致运行速度变慢。

使用局部值并将其引用到全局值如何。我想它可以让你更快

global a
a = []
def test(): 
    global a
    b = [1,2,3,4]
    a = b
....

嗯。。我还必须用cProfiler测试它,使用局部值并引用全局值怎么样。我想它可以让你更快

global a
a = []
def test(): 
    global a
    b = [1,2,3,4]
    a = b
....

嗯。。我还必须用cProfiler对其进行测试,因此最终我无法找到一个令人满意的解决方案。 我最初使用了上面delnan提出的解决方案

a[:] = func(a)[:]
以及预先分配一定大小的数组。
很抱歉将此添加为我的答案,因为我不知道如何/如果可能,接受delnans的评论作为答案…

因此,最终我无法找到满意的解决方案。 我最初使用了上面delnan提出的解决方案

a[:] = func(a)[:]
以及预先分配一定大小的数组。
很抱歉将此添加为我的答案,因为我不知道如何/如果有可能接受delnans注释作为答案…

简而言之,在Python中,您对内存细节完全没有控制权。即使是切片分配也很容易触发重新分配,从而移动项目。有些实现可能会停止世界,并为整个堆紧凑,只不过是在你的环的中间。我对这个想法感到非常惊讶,因为这会使PyFFTW工作方式的想法完全无用,不是吗?!是的,这就是为什么听到这件事我很惊讶。如果您坚持使用CPython(因为PyFFTW是一个C库,它也仅限于此),并且不调整列表的大小,那么您可能会很好。只有更奇特的垃圾收集器和超出已分配大小的列表增长(大多数数据结构都有一点过度分配,因此在重新分配之前可以先分配一些项)才可能导致严重的问题(从静默更改未使用内存的错误到静默数据损坏)。好的。这是非常令人失望的,因为我必须寻找一种完全不同的方法来做这件事,因为我的算法正在做数以百万计的FFT和逆FFT。。。整个算法就是基于此!一个列表(以及所有其他集合)只分配这么多内存。当您添加更多项目时,您需要重新分配(即从操作系统获取一个新的、完全不相关的内存块,并将您的内容复制到那里),因为您无法随心所欲地调整现有内存块的大小。看见其他语言都存在同样的问题。但在C语言中,您知道何时重新分配内存,因为没有人为您进行内存管理。你可能仍然可以做你想做的事情,你只需要事先准备一个适当大小的列表,简而言之,你在Python中对内存细节完全没有控制能力。即使是切片分配也很容易触发重新分配,从而移动项目。有些实现可能会停止世界,并为整个堆紧凑,只不过是在你的环的中间。我对这个想法感到非常惊讶,因为这会使PyFFTW工作方式的想法完全无用,不是吗?!是的,这就是为什么听到这件事我很惊讶。如果您坚持使用CPython(因为PyFFTW是一个C库,它也仅限于此),并且不调整列表的大小,那么您可能会很好。只有更奇特的垃圾收集器和超出已分配大小的列表增长(大多数数据结构都有一点过度分配,因此在重新分配之前可以先分配一些项)才可能导致严重的问题(从静默更改未使用内存的错误到静默数据损坏)。好的。这是非常令人失望的,因为我必须寻找一种完全不同的方法来做这件事,因为我的算法正在做数以百万计的FFT和逆FFT。。。整个算法就是基于此!一个列表(以及所有其他集合)只分配这么多内存。当您添加更多项目时,您需要重新分配(例如