'str' object does not support item assignment

PythonString

Python Problem Overview


I would like to read some characters from a string s1 and put it into another string s2.

However, assigning to s2[j] gives an error:

s2[j] = s1[i]

# TypeError: 'str' object does not support item assignment

In C, this works:

int i = j = 0;
while (s1[i] != '\0')
    s2[j++] = s1[i++];

My attempt in Python:

s1 = "Hello World"
s2 = ""
j = 0

for i in range(len(s1)):
    s2[j] = s1[i]
    j = j + 1

Python Solutions


Solution 1 - Python

The other answers are correct, but you can, of course, do something like:

>>> str1 = "mystring"
>>> list1 = list(str1)
>>> list1[5] = 'u'
>>> str1 = ''.join(list1)
>>> print(str1)
mystrung
>>> type(str1)
<type 'str'>

if you really want to.

Solution 2 - Python

In Python, strings are immutable, so you can't change their characters in-place.

You can, however, do the following:

for c in s1:
    s2 += c

The reasons this works is that it's a shortcut for:

for c in s1:
    s2 = s2 + c

The above creates a new string with each iteration, and stores the reference to that new string in s2.

Solution 3 - Python

> assigning to s2[j] gives an error

Strings are immutable so what you've done in C won't be possible in Python. Instead, you'll have to create a new string.

> I would like to read some characters from a string and put it into > other string.

Use a slice:

>>> s1 = 'Hello world!!'
>>> s2 = s1[6:12]
>>> print(s2)
world!

Solution 4 - Python

Strings in Python are immutable (you cannot change them inplace).

What you are trying to do can be done in many ways:

Copy the string:

foo = 'Hello'
bar = foo

Create a new string by joining all characters of the old string:

new_string = ''.join(c for c in oldstring)

Slice and copy:

new_string = oldstring[:]

Solution 5 - Python

Other answers convert the string to a list or construct a new string character by character. These methods can be costly, especially for large strings. Instead, we can use slicing to get the parts of the string before and after the character that is changed, and combine those with the new character.

Here I modify the example code from Crowman's answer to replace a single character in the string using string slicing instead of conversion to a list.

>>> str1 = "mystring"
>>> pos = 5
>>> new_char = 'u'
>>> str2 = str1[:pos] + new_char + str1[pos+1:]
>>> print(str2)
mystrung
>>> type(str2)
<class 'str'>

Solution 6 - Python

Another approach if you wanted to swap out a specific character for another character:

def swap(input_string):
   if len(input_string) == 0:
     return input_string
   if input_string[0] == "x":
     return "y" + swap(input_string[1:])
   else:
     return input_string[0] + swap(input_string[1:])

Solution 7 - Python

Performant methods

If you are frequently performing index replacements, a more performant and memory-compact method is to convert to a different data structure. Then, convert back to string when you're done.

list:

Easiest and simplest:

s = "TEXT"
s = list(s)
s[1] = "_"
s = "".join(s)
bytearray (ASCII):

This method uses less memory. The memory is also contiguous, though that doesn't really matter much in Python if you're doing single-element random access anyways:

ENC_TYPE = "ascii"
s = "TEXT"
s = bytearray(s, ENC_TYPE)
s[1] = ord("_")
s = s.decode(ENC_TYPE)
bytearray (UTF-32):

More generally, for characters outside the base ASCII set, I recommend using UTF-32 (or sometimes UTF-16), which will ensure alignment for random access:

ENC_TYPE = "utf32"
ENC_WIDTH = 4

def replace(s, i, replacement):
    start = ENC_WIDTH * (i + 1)
    end = ENC_WIDTH * (i + 2)
    s[start:end] = bytearray(replacement, ENC_TYPE)[ENC_WIDTH:]


s = "TEXT HI ひ RA ら GA が NA な DONE"
s = bytearray(s, ENC_TYPE)

# Performs s[1] = "_"
replace(s, 1, "_")

s = s.decode(ENC_TYPE)

Though this method may be more memory-compact than using list, it does require many more operations.

Solution 8 - Python

In my genius rookie situation I tried to add keys / values to a dictionary incorrectly. like so.

mydict = {}
mydict = mydict['my_key'] = 'my_value'

Where it should be.

mydict['my_key'] = 'my_value' 

Solution 9 - Python

The 'str' is an immutable data type. Therefore str type object doesn't support item assignment.

s1 = "Hello World"
s2 = ['']*len(s1)
j = 0
for i in range(len(s1)):
s2[j]=s1[i]
j = j + 1
print(''.join(s2)) # Hello World

Solution 10 - Python

How about this solution:

str="Hello World" (as stated in problem) srr = str+ ""

Solution 11 - Python

Hi you should try the string split method:

i = "Hello world"
output = i.split()

j = 'is not enough'

print 'The', output[1], j

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRasmi Ranjan NayakView Question on Stackoverflow
Solution 1 - PythonCrowmanView Answer on Stackoverflow
Solution 2 - PythonNPEView Answer on Stackoverflow
Solution 3 - PythonwimView Answer on Stackoverflow
Solution 4 - PythonBurhan KhalidView Answer on Stackoverflow
Solution 5 - PythonLeland HepworthView Answer on Stackoverflow
Solution 6 - PythonJean-Emile Leconte IIView Answer on Stackoverflow
Solution 7 - PythonMateen UlhaqView Answer on Stackoverflow
Solution 8 - PythonJohn CarrView Answer on Stackoverflow
Solution 9 - PythonAnkit PatidarView Answer on Stackoverflow
Solution 10 - Pythonuser2643900View Answer on Stackoverflow
Solution 11 - PythonDevzzoneView Answer on Stackoverflow