逗号后跟变量赋值如何连接



我仍处于学习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'

由此可以看出,中间的三行交换了ab的值。在 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        

由此可以看出,发生以下情况:

  1. 加载expression并检查其真实性。如果True,循环将立即退出。
  2. 加载、更新、交换和存储checkexpression的值。
  3. check的值与expression的值进行比较。如果False,循环将跳转到起点。否则,将返回False
  4. 返回 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

相关内容

  • 没有找到相关文章

最新更新