1

My question is a slight variation of How do I pass a variable by reference? - however I still can't find a simple solution to the problem illustrated below: how can I alter the values of the outer string variables from within a for-loop?

str1 = 'before'
str2 = 'before'

for i in str1,str2:
    print "%s" % (i)
    i = "after"

for i in str1,str2:
    print "%s" % (i)

Thanks for the helpful responses below however they haven't really helped with my specific problem, the code below is less generic but better reflects my use case:

import feedparser
d = feedparser.parse('http://feeds.feedburner.com/FrontlineAudiocastPbs?format=xml')
name = d.feed.title[:127]
description = d.feed.subtitle[:255]

strs = [name,description]
for i, s in enumerate(strs):
    try:
      strs[i] = unicode(strs[i])
    except:
      strs[i] = "Invalid unicode detected!"

for s in name,description:
  print s 

You can see that the two original string variables are not being updated. The for-loop is intended to detect and handle malformed string such as the assignment to 'description'.. so any 'associated' advice would be appreciated.

I like the elegance of the list comprehension slice assignment approach below and would ideally use that technique.

Community
  • 1
  • 1
evillen
  • 103
  • 2
  • 8
  • 2
    You can't. `i` is iterating over the string values, which are immutable, not the variables. – Amber Sep 05 '12 at 16:56
  • 5
    Perhaps you want a list of strings instead of a series of variables? If you tell us more about your actual program and the data it needs, we can help you find a good solution. – Ned Batchelder Sep 05 '12 at 16:59
  • Could you provide a use case for what you're trying to do? – Lukas Graf Sep 05 '12 at 17:13

4 Answers4

5

Make a list of strings instead of dealing with them as separate variables, then you can loop over them with enumerate:

strs = ['before', 'before']
for i, s in enumerate(strs):
    print s
    strs[i] = "after"

print strs
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
3

One workaround is to structure your data differently, for example by using:

d = {'str1': 'before', 'str2': 'before'}
for i in d:
    print d[i]
    d[i] = "after"

The important thing is that this variable is mutable (as discussed in your link).

Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
1
strs = ['before', 'before']
strs[:] = ['after' for s in strs]
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • That adds an unnecessary layer of confusion I find. This way you're not only changing the list, you're replacing it with a completely new list. – Lukas Graf Sep 05 '12 at 17:05
  • @Lukas: Incorrect. Slice assignment preserves the original list, keeping its references intact. – Ignacio Vazquez-Abrams Sep 05 '12 at 17:06
  • Oh, right, my mistake. I somehow read it as `strs = ['after' for s in strs[:]]` (Using slicing to create a copy of the list, not slice assignment) – Lukas Graf Sep 05 '12 at 17:11
-1
str1 = 'before'
str2 = 'before'

import sys
currentobject = sys.modules[__name__]

for i in 'str1', 'str2':
    setattr(currentobject, i, 'after')

for i in str1,str2:
    print "%s" % (i)
George
  • 1,036
  • 2
  • 11
  • 23