Python: Как сохранить место в переменной памяти при присваивании? - PullRequest
2 голосов
/ 10 марта 2011

Я все еще довольно новичок в Python, так что простите мне этот вопрос, если это глупо. Я не смог найти ответ через гугл ...

Я использую PyFFTW в своем коде, который имеет этап планирования, на котором вы передаете две переменные (источник / назначение), которые вы преобразовываете из / в. Затем, когда вы вызываете БПФ, вы работаете с точным пространством памяти, где эти переменные находились на этапе планирования. Таким образом, любые операции, выполняемые с переменными, должны быть выполнены, чтобы расположение этих двух переменных в памяти не изменилось. Я нашел операторы *=, += и т. Д., Которые делают это для стандартных математических операторов. Однако в моей программе мне нужно применить функцию к переменной, которая должна вернуть ее в ту же ячейку памяти. Как это сделать?!

Изначально я использовал нарезку следующим образом:

a[:] = func(a)[:]

Однако я только что понял, что это очень медленно (мой код примерно на 10% медленнее). Так кто-нибудь знает, как это сделать?

Любая помощь очень ценится. Заранее спасибо!

Ответы [ 4 ]

0 голосов
/ 31 декабря 2013

Так что в итоге я не смог найти удовлетворительное решение проблемы.Сначала я использовал решение, предложенное Делнаном выше

a[:] = func(a)[:]

, и предварительно выделил массивы определенного размера.Извините, что добавил это как мой ответ, так как я не мог понять, как / если возможно принять комментарии delnans в качестве ответа ...

0 голосов
/ 10 марта 2011

Это то, что вы пытаетесь сделать?

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]
>>>

Ваш исходный код копирует массив после его возврата.Обычно это бесполезная практика, способствующая замедлению работы.

0 голосов
/ 11 марта 2011

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

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

гм .. Мне бы тоже пришлось проверить это с помощью cProfiler

0 голосов
/ 10 марта 2011

Ваша переменная является изменяемым типом, поэтому ваша функция может просто работать с ней напрямую.

Вы по-прежнему не сможете использовать функции и операторы, которые собираются создавать копии и / или делать новые назначения(те же, которые вы уже не могли использовать), но прямые мутации аргумента вашей функции будут видны вне функции.

...