лучший способ обновить значения переменных внешней области из цикла for?

3

Этот вопрос связан с моим предыдущим вопросом здесь: python update external передал значение из цикла for.

Исходя из фона Perl, никогда не было проблемой передать переменную по ссылке и обновить значение из дочерней области, как в примере ниже для цикла:

#!/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

Хотя это не идеально, это было бы нормально, если бы я мог сделать функцию "changeValue" вызовом изнутри цикла, вместо того, чтобы называть их индивидуально, как указано выше, - но затем я возвращаюсь к оригиналу "не может передать переменную по ссылке".

Я уверен, что должен быть простой и менее запутанный Pythonic способ добиться того, что я после?

  • 2
    в чем реальная разница между s1 = change(s1) и change(s1) ? Обратите внимание , что питон действительно проходит по ссылке, это просто , что назначение создает новую ссылку и некоторые типы (интермедиат, ул ...) неизменны, так что нет никакого реального способа изменить объект , что ссылка ссылки ...
  • 0
    Кстати: почему вы продолжаете показывать пример кода, а не ваш реальный код? Реальный код всегда лучший способ получить полезную помощь.
Показать ещё 2 комментария
Теги:
scope
for-loop
reference

2 ответа

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
    Даже не упоминайте globals .
  • 0
    @NedBatchelder - почему бы и нет? Если пользователь хочет отстрелить свои ноги, это его дело ... (и, насколько я знаю, стандарт даже разрешает модификацию globals в отличие от locals ).
Показать ещё 4 комментария
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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню