剧透警告我已经用这段代码解决了 LeetCode 问题 13(罗马到整数):
roman_numbers = [('I', 1), ('V', 5), ('X', 10), ('L', 50), ('C', 100), ('D', 500), ('M', 1000)]
class Solution:
def get_value(self, number):
return dict(roman_numbers)[str(number)]
def romanToInt(self, s: str) -> int:
result = 0
letter_list = list(letter for letter in s)
for letter in s:
try:
if self.get_value(letter_list[0]) >= self.get_value(letter_list[1]):
result += self.get_value(letter_list[0])
letter_list.remove(letter_list[0])
else:
result -= self.get_value(letter_list[0])
letter_list.remove(letter_list[0])
except IndexError:
result += self.get_value(letter_list[0])
return result
速度不快,记忆力也不强,但我不在乎,因为我是初学者,我只想把事情做好,一旦我能处理好基本的事情,我就会担心这些事情。
问题是,在我的
romanToInt
函数中,我多次使用 self.get_value(letter_list[x])
,我认为有一个存储该值但每次调用 letter_list.remove(letter_list[0])
函数时都会更新的变量可读性会更好,所以我可以有这样的东西:
if letter0 >= letter1:
result += letter0
我发现我可以通过在 for 循环中创建变量来做到这一点,这样每次循环它都会更新:
for letter in s:
letter0 = self.get_value(letter_list[0])
letter1 = self.get_value(letter_list[1])
try:......
但是我一直有很多与变量不更新相关的问题所以我想知道是什么让它更新?事实上,有一个功能?事实上,当一个循环结束时,变量被删除只是为了在下一个循环开始时再次创建?
让变量发生变化的是赋值操作:
letter0 = ...
赋值右边的内容(=,+=等)首先被评估/执行,然后将结果填充到变量中。但是不,在 Python 中,当您到达定义它们的循环(范围)的底部时,变量不会消失。下一个赋值只是替换之前引用的变量。
所以,变量只是引用 objects 的名称。您似乎期望一个变量包含一个将被动态执行的 expression。那不是那样的。变量保存 表达式的结果。如果你使用下面的赋值语句:
letter0 = self.get_value(letter_list[0])
Then
letter0
现在指的是通过计算表达式 self.get_value(letter_list[0])
得到的对象。在这种情况下,它是一些 str
对象。之后在代码中使用该变量时,它的计算结果只是 that string object。它不会重新计算赋值语句中使用的表达式:self.get_value(letter_list[0])
.
有两种方法可以“更新”变量。
虽然这是两个不同的东西。实际上,只有 (1) 是更新变量。另一个是改变一些对象.
现在,您真的应该通读 Ned Batchelder 的整本优秀作品关于 Python 名称和值的事实和神话(他是 StackOverflow 的传奇人物)。但我想强调一点:很多不同的东西都是作业,而不仅仅是简单的作业
<some-var> = <some-expression>
例如
result = some_function()
以下是您可以分配给名称的各种方式
X
:
X = ...
for X in ...
[... for X in ...]
(... for X in ...)
{... for X in ...}
class X(...):
def X(...):
def fn(X): ... ; fn(12)
with ... as X:
except ... as X:
import X
from ... import X
import ... as X
from ... import ... as X
至于mutating一个对象,一般是通过一些mutator方法完成的,例如:
my_object.mutator_method(some_arg)
例如,这里有两个不同的 mutator 方法通过变量
mylist
在同一个对象上调用:
mylist.append(42)
mylist.pop()
注意,运算符和其他各种语言结构也可以改变一个对象,因为在幕后,最终会调用一个改变器方法!
mylist += [42] # This one actually is an assignment too!
mylist[i] = 42 # This one is *not an assignment*!
注意最后一个!这实际上不是作业!