在C ++中,允许返回对值的引用,然后写入,例如:
#include <iostream>
int main() {
int data[] = {1,2,3,4};
std::cout << data[0] << " " << data[1] << " " << data[2] << " " << data[3] << '\n';
auto key =
[](int data[]) -> int &
{
return data[1];
};
key(data) = 6;
std::cout << data[0] << " " << data[1] << " " << data[2] << " " << data[3] << '\n';
}
这是有效的,C ++ 11代码的输出是:
1 2 3 4
1 6 3 4
同时,在Python 3中:
data = (1,2,3,4)
key = lambda d: d[2]
key(data) = 5
print(data)
这有效,但不讨好,因为它很好地说明我可能不会分配给函数调用:
File "gett.py", line 4
key(data) = 5
^
SyntaxError: can't assign to function call
那么如何传递一个可用于获取和设置的callable? Python 3的方法是什么?
我的特殊用例是我有这样的东西:
#Data = namedtuple('Data', ['meta', 'value', 'othervalue'])
# since namedtuples are not muteable
class Data:
def __init__(self, meta, value, othervalue):
self.meta = meta; self.value=value; self.othervalue=othervalue;
data = [Data('blabla', None, 543), Data('blabla', 5, 54), Data('blabla', 324, None), Data('blabla', None, 34), Data('blabla', 432, None)]
我希望将每个None
替换为value
或othervalue
的上一个值,如下所示:
def nearest_before_interpolate(self, l, key):
last = 0
for i in range(len(l)):
with getattr(l[i], key) as val:
if val == None:
setattr(l[i], key, last)
else:
last = val
现在我将密钥作为字符串传递,但如果这是一个通用的lambda
,它可以以任何它认为合适的方式提取正确的字段(不是它真的需要这种灵活性,但我是比如lambda
我想的更多的字符串,也更适合这个用例。)
有没有人有一个很好的建议怎么做?
答案 0 :(得分:2)
这里有两个问题:
python语法不允许直接赋值函数调用的返回值 - can't assign to function call
。就这么简单。
元组是不可变的,因此您无法替换项目,只能更改它的值。这显然是您的简化示例中的问题 - 您无法更改数字的值.5是5。
解决这些问题,这是一个概念证明:
data = ([1],[2],[3],[4])
key = lambda d: d[2]
v = key(data)
v.append(0)
print(data) # ([1], [2], [3, 0], [4])
更新:抱歉,我有点困惑,因为你使用元组但后来列表。
好吧,你几乎可以做到,只是没有你想要的语法:
class wrapper():
def __init__(self, d, i):
self.d = d
self.i = i
def set(self, v):
self.d[self.i] = v
data = [1,2,3,4]
key = lambda d: wrapper(d, 2)
v = key(data)
v.set(5)
print(data) # [1, 2, 5, 4]
在python中你不能重载赋值,所以你需要一些其他方法来改变值。在这里我选择了一个函数调用,但你可以使用任何可以intercepted的东西(例如:设置一个属性)。
答案 1 :(得分:0)
我认为这是最接近你没有主要hackery的地方:
operator>>