2015-11-26 5 views
1

Я пытаюсь создать функцию, которая обновляет аргументы InPlace (в основном ради любопытства):Python inplace обновление аргументов функции?

def inplaceUpdate(f, inputs): 
    for i in inputs: 
     i = f(i) 

У меня есть три входа:

x = 1 
y = 2 
z = 3 

и функция f:

f = lambda i: i**2 

Я бы хотел (а) ввести код:

inplaceUpdate(f, [x, y, z]) 

Тогда я хотел бы получить значения x, y и z для замены на место. Это возможно?

x = 1 
y = 4 
z = 9 
+0

@oxfn Я попробовать его, и он не обновляет 'x',' y' и 'z', если это так, что бы уже было совсем что-то; В первый раз вопрос также был бы ответом;) – applecider

ответ

3

В Python целые числа являются неизменяемыми. Есть вопрос по теме here.

Идея состоит в том, что вы не можете изменить значение ссылок x, y и z. Это означает, что если вы делаете:

x = 2 
y = 3 
z = 4 
some_func([x, y, z]) 

Там нет никакого способа, которым some_funcизменяет значения переменных x, y и z.

Однако списки изменяемые, и вы могли бы сделать:

def some_func(l): 
    l[:] = [i*2 for i in l] 

l = [2, 3, 4] 
some_func(l) 

print l # the array has changed 

И это было бы действительно изменить список. Это связано с тем, что операция l[:]=... присваивает сдерживанию списка, вместо переназначения ссылки - то, что будет l=....

+0

Я вижу, это правильный ответ, спасибо за рассуждения – applecider

+0

Быстрый вопрос: есть ли способ узнать, является ли переменная изменчивой или нет, т.е. 'ismutable (x)', которая возвращает логическое значение? – applecider

+0

Нет. Я так не думаю. – ppperry

2

Похоже, что вы хотите отобразить список. Существует красивая встроенная функция map для этого

# Declare lambda somewhere 
f = lambda i: i**2 

# Map your inputs 
input = [1, 2, 3] 
result = map(f, input) 
+0

Спасибо за очки, я знал о картах, но я хотел бы обновить на месте, т. Е.не используйте знак равенства, x, y и z - это сложные объекты, которые я не хочу собирать в список, я хочу сохранить их как отдельные переменные, но выполнить одну и ту же операцию для их обновления на месте (да, Я такой ленивый, что я не хочу использовать знак равенства: jk это больше упражнение из любопытства) – applecider

0

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

input = [1, 2, 3] 
ls = [x**2 for x in input] 
-1

Невозможно изменить значения переменных вызывающей функции без использования уродливого хакера. Если вы сохранили ссылку на список mutable, который вы создали в [x,y,z], функция inplaceUpdate может изменить его.

Для выполнения этой задачи с помощью уродливых хаков:

def inPlaceUpdate(inputs): 
    frame = sys._getframe(1) 
    for input in inputs: 
     i = f(input) 
     for k,v in frame.f_locals.iteritems(): 
      if v == input: 
       frame.f_locals[k] = i 
       break 
     else: 
      for k,v in frame.f_globals.iteritems(): 
       if v == input: 
       frame.f_globals[k] = i 
       break 
+1

№ Язык Python является передачей по ссылке. Тем не менее, некоторые типы являются неизменяемыми, и они ведут себя так же, как и пропускная способность. Но ваше утверждение неверно - оно применимо только к определенным типам. 'int',' str', 'tuple', но не' list' или 'dict'. – MariusSiuram

+0

Это неправда. Списки передаются по ссылке (вернее, ссылки передаются по значению), и их содержимое может быть изменено функцией без каких-либо хаков. – interjay

+0

@MariusSiuram Извините, меня всегда путают по поводу пропусков по сравнению с передачей по значению. – ppperry

Смежные вопросы