从for循环中更新外部作用域变量值的最佳方式



这个问题与我之前的问题有关:python从for循环中更新外部传递的值。

来自Perl背景,通过引用传递变量并在子范围内更新值从来都不是问题,如下面的for循环示例所示:

#!/usr/bin/perl
my ($str1,$str2) = ('before','before');
print "before - str1:'$str1', str2:'$str2'n";
foreach my $str($str1,$str2){$str = 'after'}
print "after - str1:'$str1', str2:'$str2'n";

我知道在Python中这是不可能的,因为变量是通过值而不是通过引用导入的,到目前为止,我在Python中找到的唯一能实现我所需要的解决方案是:

def changeValue(str):
  return 'after'
str1 = 'before'
str2 = 'before'
for s in str1,str2: print s
str1 = changeValue(str1)
str2 = changeValue(str2)
for s in str1,str2: print s

虽然不理想,但如果我可以从for循环中调用函数"changeValue",而不是像上面那样单独调用它们,那么这将是OK,但之后我又回到了最初的"无法通过引用传递变量"问题。

我确信,一定有一种简单而不那么复杂的Python方式来实现我想要的东西?

在python中,执行类似操作的方法几乎可以肯定是使用字典来存储数据:

d = {'s1':'before','s2':'before'}
for k in d.keys():
    print d[k]
for k in d.keys():
    d[k] = 'after'
    print d[k]

还有其他解决方案(修改globals字典是有效的,但由于其导致几乎不可能读取/调试的代码,因此被高度挖掘)。也许如果我们知道这方面的实际用例,我们可能能够提供一些更好的建议。

解决方案是停止使用自变量,而是将它们存储在字典中。例如:

def changeValue(str):
  return 'after'
data = {
    'str1': 'before',
    'str2': 'before',
}
for k, v in data.iteritems():
    print k, v
# as you had it:
data['str1'] = changeValue(str1)
data['str2'] = changeValue(str2)
# with a loop:
for key in ['str1', 'str2']:
    data[key] = changeValue(data[key])
# or a nicer way:
for k, v in data.iteritems():
    data[k] = changeValue(v)
for k, v in data.iteritems():
    print k, v

最新更新