views:

240

answers:

3

I want to change the value of a particular string index, but unfortunately

string[4] = "a"

raises a TypeError, because strings are immutable ("item assignment is not supported").

So instead I use the rather clumsy

string = string[:4] + "a" + string[4:]

Is there a better way of doing this?

+4  A: 
mystring=list("abcdef")
mystring[4]="Z"
print ''.join(mystring)
ghostdog74
Eww, ''.join() is pretty nasty.
Aiden Bell
Not really. `str.join()` is useful for all sorts of things, and this is one of them. `''.join(...)` is a fairly common idiom.
Devin Jeanpierre
str.join is useful for building strings, but I don't think this one's a good idea. If you're only replacing one character, it's going to do a lot more work. Also, try `a = list(u"か"*1000000)`; that uses about 40 megs of memory on my system. You're better off with `def replace_char(s, idx, c): return s[:idx] + c + s[idx:]` unless you're doing a lot of them at once.
Glenn Maynard
BTW. The given example code samples appear to do two different things. The first implies replacement. The second is actually an insert. You should probably show how to do both in this example.
S.Lott
Although the request for "better" is a little subjective, this appears to be just as clumsy. A change that avoids the issue rather than another way of circumventing the design of the String class might be in order.
Dustman
A: 
>>> from UserString import MutableString
>>> s = MutableString('abcd')
>>> s[2] = 'e'
>>> print s
abed
ezod
From the Python standard library docs: This UserString class from this module is available for backward compatibility only. If you are writing code that does not need to work with versions of Python earlier than Python 2.2, please consider subclassing directly from the built-in str type instead of using UserString (there is no built-in equivalent to MutableString).
Tendayi Mawushe
From the docs for MutableString: "But the purpose of this class is an educational one: ... A faster and better solution is to rewrite your program using lists." http://pydoc.org/2.2.3/UserString.html
asveikau
In addition, MutableString is deprecated in 2.6 and removed in 3.0.
jamessan
+5  A: 

The strings in Python are immutable, just like numbers and tuples. This means that you can create them, move them around, but not change them. Why is this so ? For a few reasons (you can find a better discussion online):

  • By design, strings in Python are considered elemental and unchangeable. This spurs better, safer programming styles.
  • The immutability of strings has efficiency benefits, chiefly in the area of lower storage requirements.
  • It also makes strings safer to use as dictionary keys

If you look around the Python web a little, you’ll notice that the most frequent advice to "how to change my string" is "design your code so that you won’t have to change it". Fair enough, but what other options are there ? Here are a few:

  • name = name[:2] + ‘G’ + name[3:] - this is an inefficient way to do the job. Python’s slice semantics ensure that this works correctly in all cases (as long as your index is in range), but involving several string copies and concatenations, it’s hardly your best shot at efficient code. Although if you don’t care for that (and most chances are you don’t), it’s a solid solution.
  • Use the MutableString class from module UserString. While no more efficient than the previous method (it performs the same trick under the hood), it is more consistent syntactically with normal string usage.
  • Use a list instead of a string to store mutable data. Convert back and forth using list and join. Depending on what you really need, ord and chr may also be useful.
  • Use an array object. This is perhaps your best option if you use the string to hold constrained data, such as ‘binary’ bytes, and want fast code.

Plagiarized from my own page on Python insights :-)

Eli Bendersky