我仍处于学习Python的早期阶段,遇到了这种语法,但我不知道它的作用。
check, expression = expression, expression.replace('()', '').replace('[]', '').replace('{}', '')
现在我知道 str.replace() 函数是做什么的,我只是不清楚最终如何将"检查"分配给这个替换函数的串联。
上下文:
以下是上下文的完整代码,它的目的只是检查给定字符串中是否正确使用了括号:
BRACKETS = ("{","[","(","}","]",")")
list = []
#Creating a list with only the brackets in it.
for c in expression:
if (c in BRACKETS) and (c in expression):
list.append(c)
expression = ''.join(list)
while expression:
check, expression = expression, expression.replace('()', '').replace('[]', '').replace('{}', '')
if expression == check:
return False
return True
考虑以下示例:
a = 'a'
b = 'b'
temp = a
a = b
b = temp
print(a) # 'b'
print(b) # 'a'
由此可以看出,中间的三行交换了a
和b
的值。在 Python 中,可以使用元组打包和解包来消除对临时变量的需求。
a = 'a'
b = 'b'
temp_tuple = b, a # tuple packing
print(temp_tuple) # ('b', 'a')
a, b = temp_tuple # tuple unpacking
print(a) # 'b'
print(b) # 'a'
现在,我们可以将这种打包和解包组合到一个表达式中。
a = 'a'
b = 'b'
a, b = b, a
print(a) # 'b'
print(b) # 'a'
您的代码将expression
的原始值保存到check
中,并将expression
的更新版本保存回expression
。然后,它比较这两个变量,以查看expression
是否被所有replace
调用更改。
编辑:关于Python是否通过代码段三次的评论,我们可以使用dis
模块来反汇编测试函数的Python字节码。
from dis import dis
def test(expression):
while expression:
check, expression = expression, expression.replace('()', '').replace('[]', '').replace('{}', '')
if expression == check:
return False
return True
print dis(test)
这将打印以下内容(带有一些注释):
# while expression:
4 0 SETUP_LOOP 75 (to 78)
>> 3 LOAD_FAST 0 (expression) # start
6 POP_JUMP_IF_FALSE 77 # jump to exit
# check, expression = [...]
5 9 LOAD_FAST 0 (expression)
12 LOAD_FAST 0 (expression)
15 LOAD_ATTR 0 (replace)
18 LOAD_CONST 1 ('()')
21 LOAD_CONST 2 ('')
24 CALL_FUNCTION 2
27 LOAD_ATTR 0 (replace)
30 LOAD_CONST 3 ('[]')
33 LOAD_CONST 2 ('')
36 CALL_FUNCTION 2
39 LOAD_ATTR 0 (replace)
42 LOAD_CONST 4 ('{}')
45 LOAD_CONST 2 ('')
48 CALL_FUNCTION 2
51 ROT_TWO
52 STORE_FAST 1 (check)
55 STORE_FAST 0 (expression)
# if check == expression:
6 58 LOAD_FAST 0 (expression)
61 LOAD_FAST 1 (check)
64 COMPARE_OP 2 (==)
67 POP_JUMP_IF_FALSE 3 # jump to start
# return False
7 70 LOAD_GLOBAL 1 (False)
73 RETURN_VALUE
74 JUMP_ABSOLUTE 3 # jump to start
>> 77 POP_BLOCK # exit
# return True
8 >> 78 LOAD_GLOBAL 2 (True)
81 RETURN_VALUE
由此可以看出,发生以下情况:
- 加载
expression
并检查其真实性。如果True
,循环将立即退出。 - 加载、更新、交换和存储
check
和expression
的值。 - 将
check
的值与expression
的值进行比较。如果False
,循环将跳转到起点。否则,将返回False
。 - 返回
True
的值。仅当循环退出时,才会发生这种情况,因为第一步中expression
的值不真实。
我认为check, expression = [...]
行中唯一需要注意的是指令ROT_TWO
的使用,它交换了两个最顶层的堆栈项目。在第 9 行,加载 expression
的值。在第 12-48 行,加载并更新expression
的值,将第 9 行加载的值推回堆栈中。然后,在第 51 行,交换这两个值。
您询问的行等效于:
check = expression
expression = expression.replace('()', '').replace('[]', '').replace('{}', '')
Python 允许使用单个=
进行多个赋值。左侧的每个变量都从右侧分配一个相应的值。
解释
例如:
x, y = 1, 2
x
将用 1 初始化,y
用 2 初始化。
您也可以使用它来解包元组。例如
>>> def foo(): return 1, 2
>>> x = foo()
>>> x # It is tuple
(1, 2)
>>> x, y = foo() # Value of 'x' is 1 and 'y' is 2
>>> x
1
>>> y
2
您也可以使用它来交换两个数字作为a, b = b, a