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

时间:2016-03-01 22:02:08

标签: python python-3.x

我仍然处于学习Python的早期阶段,并且遇到了这种语法,但我不知道它的作用。

check, expression = expression, expression.replace('()', '').replace('[]', '').replace('{}', '')

现在我知道了str.replace()函数的作用,我不清楚最终是如何将“check”分配给这个替换函数的连接。

上下文

以下是上下文的完整代码,其目的只是检查在给定字符串中正确使用了哪些括号:

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

3 个答案:

答案 0 :(得分:1)

您提出的问题相当于:

check      = expression
expression = expression.replace('()', '').replace('[]', '').replace('{}', '')

Python允许使用单个=进行多次分配。左侧的每个变量都从右侧分配了相应的值。

答案 1 :(得分:1)

考虑以下示例:

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的值在第一步中并不真实。
  5. 我认为check, expression = [...]行中唯一需要注意的是使用ROT_TWO指令,swaps the two top-most stack items.第9行expression的值已加载。在第12-48行,expression的值已加载并更新,将第9行上加载的值推回堆栈中。然后,在第51行,交换这两个值。

答案 2 :(得分:0)

<强>解释

例如:

x, y = 1, 2

x将初始化为1&amp; 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