Python字符串-字符串的不变性

Python字符串-字符串的不变性,python,python-3.x,Python,Python 3.x,我想知道,如果Python字符串是不可变的,那么这段代码为什么工作以及它是如何工作的 a = input() for i in a: if i.isupper(): print(i.lower(), end='') else: print(i.upper(), end='') 这将更改字符串中的字符。以前我知道字符串是不可变的,所以我在列表中转换它,然后更改它,并将列表连接回字符串。现在我认为我当时写的所有代码都毫无价值。你说得对,字符串是不可变

我想知道,如果Python字符串是不可变的,那么这段代码为什么工作以及它是如何工作的

a = input()
for i in a:
    if i.isupper():
        print(i.lower(), end='')
    else:
        print(i.upper(), end='')

这将更改字符串中的字符。以前我知道字符串是不可变的,所以我在列表中转换它,然后更改它,并将列表连接回字符串。现在我认为我当时写的所有代码都毫无价值。

你说得对,字符串是不可变的。您必须了解您调用的方法是如何工作的

if i.isupper():
        print (i.lower(),end='')
    else:
        print (i.upper(),end='')
方法lower()返回所有基于大小写的字符都已小写的字符串的副本

所以这个方法返回一个副本,而不是原始的。只有当使用的单词都是小写时,它才会返回原始字符串,在这种情况下,它将返回原始字符串。不是它的新副本(新变量)

对于相同的上限,它们创建一个新变量

感谢bruno desthuilliers添加此内容以了解更多信息
关于“关于Python名称和值的事实和神话”

str.lower
str.upper
和其他字符串操作返回副本。它们没有在适当的地方工作。您可以通过阅读文档来检查这一点;:

str.lower()

返回字符串的副本,其中所有大小写字符都转换为小写

复制在这里意味着一个新字符串,而不是原地突变的旧字符串。您还可以通过在对字符串进行变异后打印字符串来验证这一点:

x = 'HELLO'
y = x.lower()
print(x)  # 'HELLO'

Python中的字符串是不可变的,这意味着一旦将字符串变量分配给字符串(例如
a='Hello'
),字符串的内容就不能像列表对象那样更改。 在上面的代码中,您正在转换字符串,而不是更改字符串变量的内容

a=input()
for i in a:
    if i.isupper():
        print (i.lower(),end='')
    else:
    print (i.upper(),end='')
print(a)
如果运行此代码,您将看到a的值与您输入的值相同。strings方法lower()和upper()只返回字符串的一个副本。

它们是不可变的。乙二醇

text = 'hello'
text.upper()
print(text) # hello
尽管您已对
text
变量调用了
upper
,但其值没有更改。与列表相比,列表是可变的

lst = [1,2,3]
lst.append(4)
print(lst) # [1,2,3,4]

它们是不可变的。不能按索引修改字符串的各个部分。大多数字符串函数从现有字符串返回一个新字符串,因此如果要存储新返回的字符串,必须创建一个新对象。原始字符串要么不受影响,要么在指向它的变量更改为指向其他对象(如新字符串对象)时丢失

但是,如何将字符串文字附加到现有的字符串对象? 比如:


现在在下面的例子中,我返回一个新字符串并创建一个新对象,旧字符串将被垃圾收集器拾取 s=‘你好,世界’

s=s.replace('l','i'))

印刷品

a='banana'
x=''
对于范围内的i(len(a)):
如果i==4:
x+='t'
其他:
x+=a[i]#没有变异a,因为我显然制造了一个新对象
#但是这种连接不被认为是突变吗,
#还是x也在“重新创建”?
打印(x)
a=a+x#在原始对象上附加某些内容,还是我正在创建一个新对象?
印刷品(a)
您还可以做什么(这绝对不是突变):
a='banana'
印刷品(a)
对于我来说,在一个:
如果i.isupper():
打印(i.lower(),end='')
打印(i,end='')
其他:
打印(i.upper(),end='')
打印(i,end='')
a=a.上()
打印('\n'+a)
对于我来说,在一个:
如果i.isupper():
打印(i.lower(),end='')
打印(i,end='')
其他:
打印(i.upper(),end='')
打印(i,end='')
a=a.下()
打印('\n'+a)
ls=[]
对于范围内的j(len(a)):
如果a[j].isupper():
ls.append(a[j].lower())
其他:
ls.append(a[j].upper())
打印(ls)
s=“”
a=s.join(ls)
印刷品(a)
输出:

banana
BbAaNnAaNnAa
BANANA
bBaAnNaAnNaA
banana
['B', 'A', 'N', 'A', 'N', 'A']
BANANA

它不会改变字符串,它会返回一个新的。你能添加预期的输出吗?你认为这里有什么变化?
i
a
都将保持不变。不可变并不意味着您无法访问字符串的某些部分并对其进行修改。但这是一个新对象(创建了一个新字符串),而旧对象仍然是不变的。。。平心而论-在使用Python的15年中,我认为我从未使用过它(只是知道它在那里,但从未发现实际需要…)感谢您的帮助“更改字符串上的值的方法之一是将其保存在数组中。”=>这不会“更改字符串上的值”,不管“将其保存在数组中”是什么意思(我想你实际上是指“从中构建列表”)。如果你在数组中创建字符串,而不是保存它。它可能会更好。你在评论中写的内容比你的答案更有意义。这可能会有帮助:(实际上应该是官方文档的一部分)。哦,是的:没有什么比“原始值”更重要的了在Python中,字符串是与Python中的任何对象(整数、列表、dict、函数、类、模块等)一样的对象。“一旦将字符串变量分配给字符串(例如a='Hello'),字符串的内容就无法更改”=>这与“分配给”无关”变量-字符串是不可变的,句号。是的,它们是不可变的,因为第二行创建了一个新字符串。
s
只是分配给字符串的名称或标签。在第一行中,
s
被分配给“Hello World”。在第二行中,
s
被分配给新字符串“Heio Worid”。原始字符串“Hello Worl”d'仍然存在,但没有分配给任何变量,因此将由垃圾收集器从内存中删除。两个字符串都没有更改,只有变量被重新分配。感谢您的解释。但是在Java中这会起作用吗?我知道需要创建一个新对象,但在Java中会自动发生吗
banana
BbAaNnAaNnAa
BANANA
bBaAnNaAnNaA
banana
['B', 'A', 'N', 'A', 'N', 'A']
BANANA