views:

66

answers:

4

Consider:

args = ['-sdfkj']
print args
for arg in args:
    print arg.replace("-", '')
    arg = arg.replace("-", '')
print args

This yields:

['-sdfkj']
sdfkj
['-sdfkj']

Where I expected it to be ['sdfkj'].

Is arg in the loop a copy?

It behaves as if it is a copy (or perhaps an immutable thingie, but then I expect an error would be thrown...)

Note: I can get the right behavior with a list comprehension. I am curious as to the cause of the above behavior.

+7  A: 

Is arg in the loop a copy?

Yes, it contains a copy of the reference.

When you reassign arg you aren't modifying the original array, nor the string inside it (strings are immutable). You modify only what the local variable arg points to.

Before assignment         After assignment

args          arg          args          arg
  |            |            |            |
  |            |            |            |
(array)        /          (array)       'sdfkj'
  |[0]        /             |[0]        
   \         /              |
    \       /               |
     '-sdfkj'            '-sdfkj'
Mark Byers
Is there a syntax to indicate that I want to operate on the reference itself?
Paul Nathan
@Paul Nathan: No. If you have a reference to the array instead of the contents then you can modify the array directly `args[i] = args[i].replace("-", '')`. So you could for example loop over the indexes using enumerate.
Mark Byers
+1  A: 

Since you mention in your question that you know it can be done using list comprehensions, I'm not going to show you that way.

What is happening there is that the reference to each value is copied into the variable arg. Initially they both refer to the same variable. Once arg is reassigned, it refers to the newly created variable, while the reference in the list remains unchanged. It has nothing to do with the fact that strings are immutable in Python. Try it out using mutable types.

A non-list comprehension way would be to modify the list in place:

for i in xrange(len(args)):
    args[i]=args[i].replace('-','')
print args
MAK
A: 

If you want to modify the actual list you have to specifically assign the changes to the list 'args.'

i.e.

for arg in args:
    if arg == "-":
        args[arg] = args[arg].replace("-", '')
Justin Hamilton
This wont work unless args is a dictionary. Assuming it's a list, you're trying to use the value as an index, which wont work.If args is a dictionary on the other hand, this works, since you'll be looping over the keys, and you get the expected behavior.
Epcylon
A: 

for a list I'd try:

args = [x.replace("-", '') for x in args]
Chris Hulan