从for循环中更新外部变量值的最佳方法?

时间:2012-09-06 15:04:40

标签: python perl reference for-loop scope

这个问题与我之前的问题有关:python update outer passed value from within a for loop

来自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中理解这是不可能的,因为变量是按 by-value 而不是 by-reference 导入的,这是迄今为止我在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-loop中进行“changeValue”调用,那么 OK - 而不是像上面那样单独调用它们 - 但是然后我回到原来的“无法通过引用传递变量”的问题。

我确信必须有一种简单且不太复杂的Pythonic方法来实现我所追求的目标?

2 个答案:

答案 0 :(得分:4)

在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词典有效,但严重错误,因为它导致代码几乎无法阅读/调试)。也许如果我们知道实际的用例,我们或许可以提供一些更好的建议。

答案 1 :(得分:2)

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

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