我对我发现的问题有一个简短的问题。在Python shell中,我可以编写test1 = "hello".upper()
,当我输入test1
时,我会按预期获得"HELLO"
。但是,如果我使用列表执行类似的操作,例如test2 = ["hello", "world"].reverse()
,并且我尝试返回test2,则什么也得不到;它是一个" NoneType"没有赋值给它。为什么会这样?为什么我可以使用作用于字符串的方法进行赋值,但是当有一个方法作用于列表时我无法进行赋值?
答案 0 :(得分:7)
这是因为list.reverse()
反转到位。这意味着它返回None
,因此当您执行test2 = ["hello", "world"].reverse()
时,您将.reverse()
(None
)的结果分配给test2
。
答案 1 :(得分:2)
首先,字符串是不可变的,而列表是可变的。这意味着您可以更改现有列表对象:
>>> l = [1,2,3]
>>> id(l)
140370614775608
>>> l.append(4)
>>> l
[1,2,3,4]
>>> id(l)
140370614775608
但是,您无法更改字符串对象;你只能用第一个作为起点创建一个新的字符串对象。
>>> s1 = "hello"
>>> id(s1)
140370614929376
>>> s1.upper()
'HELLO'
>>> id(s1)
140370614929376
在Python中,惯例是方法修改对象并返回None
,或返回一个新的修改对象,同时保留原始对象。
答案 2 :(得分:2)
你有时可以用一个对象做一件事而不用不同的对象做一些不同的事情的原因是不同的对象和不同的方法是不同的。每种方法的文档都说明了它的作用。您需要查看用于查看其功能的单个方法的文档。没有理由认为someString.upper()
将像someList.reverse()
一样工作,因为字符串不是列表,upper
不是reverse
。
答案 3 :(得分:1)
.upper()
返回一个新的String对象,相反,.reverse()
是一种破坏性方法,这意味着接收器将永远改变。
要翻转列表,您可以使用
test2 = ["hello", "world"][::-1]
也适用于字符串:
In [1]: test2 = ["hello", "world"][::-1]
In [2]: test2
Out[2]: ['world', 'hello']
In [3]: test2 = "world"[::-1]
In [4]: test2
Out[4]: 'dlrow'
功能构造内置于语言中,而不是方法中。
答案 4 :(得分:1)
.upper()返回一个新字符串,您将其分配给test1。您操作的字符串(“hello”)不会被修改。实际上,它不可能是因为字符串在Python中是不可变的。
.reverse()就地修改。这意味着对象[“hello”,“world”]被修改了。不幸的是,你没有指向该对象的变量,所以你看不到它。
这是Python的惯例。修改就地的函数返回None,而创建修改后的副本的函数返回该副本。
答案 5 :(得分:0)
这里的其余答案做了很好的解释。我只想补充一点,如果您想使用reverse
进行作业,您实际上可以使用reversed
,如下所示:
test2 = list( reversed( ["hello", "world"] ) )
# Result: ['world', 'hello']
sort
和sorted
在这方面相似。