【问题标题】:'str' object does not support item assignment“str”对象不支持项目分配
【发布时间】:2012-05-17 07:18:41
【问题描述】:

我想从字符串s1 中读取一些字符并将其放入另一个字符串s2

但是,分配给s2[j] 会出错:

s2[j] = s1[i]

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

在 C 中,这是可行的:

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

我在 Python 中的尝试:

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

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

【问题讨论】:

  • 顺便说一句,不要在 python 内置函数之后命名你的变量。如果在这里使用str 作为变量,您将无法使用str(var_that_is_not_a_string) 进行字符串转换或键入type(var_with_unknown_type) == str 等比较。
  • 查看stackoverflow.com/questions/41752946/… 修复TypeError: 'str' object does not support item assignment
  • 这对 Python 来说确实是一个负数

标签: python string


【解决方案1】:

其他答案都是正确的,但你当然可以这样做:

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

如果你真的想的话。

【讨论】:

    【解决方案2】:

    在 Python 中,字符串是不可变的,因此您不能就地更改它们的字符。

    但是,您可以执行以下操作:

    for c in s1:
        s2 += c
    

    之所以有效,是因为它是以下方面的捷径:

    for c in s1:
        s2 = s2 + c
    

    上述每次迭代都会创建一个新字符串,并将对该新字符串的引用存储在s2中。

    【讨论】:

    • @RasmiRanjanNayak:这取决于您需要对这些字符做什么。在我的回答中,我展示了如何将它们附加到另一个字符串。
    • @RasmiRanjanNayak:print " ".join(reversed("Hello world".split())).capitalize()
    • @aix:实际上是在几秒钟之内。 :D
    • 我想知道这如何影响内存,例如,如果我正在处理必须执行此操作数百万次的代码,每次迭代中新创建的字符串是否会被垃圾收集或什么..我只是在这里感到无可救药的困惑
    • @ronnieaka 在旧版本的 Python 中,这确实会产生大量垃圾。现代的有时可以优化(这是一种保证底层实现细节的语言的优点之一),但最好不要依赖它。见stackoverflow.com/questions/1316887/…
    【解决方案3】:

    分配给s2[j] 会出错

    Strings 是不可变的,所以你在 C 中所做的事情在 Python 中是不可能的。相反,您必须创建一个新字符串。

    我想从字符串中读取一些字符并将其放入 其他字符串。

    使用slice

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

    【讨论】:

      【解决方案4】:

      其他答案将字符串转换为列表或逐字符构造新字符串。这些方法的成本可能很高,尤其是对于大字符串。相反,我们可以使用切片来获取字符串中被更改字符前后的部分,并将它们与新字符组合。

      这里我修改了Crowman's answer中的示例代码,使用字符串切片而不是转换为列表来替换字符串中的单个字符。

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

      【讨论】:

        【解决方案5】:

        Python 中的字符串是不可变的(您不能就地更改它们)。

        您尝试做的事情可以通过多种方式完成:

        复制字符串:

        foo = 'Hello'
        bar = foo
        

        通过连接旧字符串的所有字符来创建一个新字符串:

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

        切片和复制:

        new_string = oldstring[:]
        

        【讨论】:

        • bar = foo 不复制字符串。
        【解决方案6】:

        如果您想将特定字符换成另一个字符,另一种方法:

        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:])
        

        【讨论】:

          【解决方案7】:

          “str”是不可变的数据类型。因此 str 类型的对象不支持项分配。

          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
          

          【讨论】:

            【解决方案8】:

            您好,您应该尝试字符串拆分方法:

            i = "Hello world"
            output = i.split()
            
            j = 'is not enough'
            
            print 'The', output[1], j
            

            【讨论】:

              【解决方案9】:

              这个解决方案怎么样:

              str="Hello World" (如问题中所述) srr = str+ ""

              【讨论】:

                【解决方案10】:

                性能方法

                如果您经常执行索引替换,一种性能更高且内存更紧凑的方法是转换为不同的数据结构。然后,完成后转换回字符串。

                列表:

                最简单最简单的:

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

                字节数组(ASCII):

                此方法使用较少的内存。内存也是连续的,尽管在 Python 中,如果你正在执行单元素随机访问,这并不重要:

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

                字节数组(UTF-32):

                更一般地说,对于基本 ASCII 集之外的字符,我建议使用 UTF-32(有时是 UTF-16),这将确保随机访问的对齐:

                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)
                

                虽然这种方法可能比使用list 更节省内存,但它确实需要更多的操作。

                【讨论】:

                  猜你喜欢
                  • 2016-10-27
                  • 2013-12-22
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-05-12
                  • 2011-07-26
                  • 2015-07-28
                  相关资源
                  最近更新 更多