目录
1.or的顺序问题
原本我以为or两边是等价的。只要有一个为True,另一个管它啥玩意都不影响。后来发现or两边条件的顺序是能够影响判断结果的,比如:
a = []
print(True or a[0])
返回正确结果:
True
交换or左右条件:
a = []
print(a[0] or True)
结果报错:
Traceback (most recent call last):
File "...\test.py", line 10, in <module>
print(a[0] or True)
IndexError: list index out of range
原因是or的判定是有顺序的,判定原理是先判断左边表达式,若为True则直接返回True;若为False则继续判断右边表达式。第一种情况下遇到True就跳过错误表达式直接返回True了,而第二种情况遇到错误表达式就直接返回Error了。
所以如果一边表达式可能报错的话,应该把它放在or右边,and同理。
2.同时赋值的顺序问题
Python3能够同时给多个变量赋值的特性十分好用,有时能省去不必要的中间变量,而且增强了可读性。比如在交换a,b的值的时候:
a, b = b, a
一行即可搞定并且十分清晰。
但之前我没有考虑到同时赋值的顺序问题,后来在处理链表的时候出现了歧义:
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
a = ListNode(1)
b = ListNode(2)
此时我想实现1->2并且把a移动到2上,于是我继续写:
a, a.next = b, b
print(a.next)
此时a的下一个节点应该指向None,结果打印出a.next显示:
<__main__.ListNode object at 0x000002A2108519F0>
而当我交换了赋值的顺序时:
a.next, a = b, b
print(a.next)
结果才是对的:
None
显而易见,在前面那种写法下,a.next中的a已经不是原本的a,而被改成了b,说明同时赋值并没有凝固住等号左侧的变量,而是按从左至右的顺序动态赋值的。但是前面写过,直接交换a,b的值是可行的,说明同时赋值能够凝固住等号右侧的值。这其中的原因是同时赋值用中间变量临时保存了等号右侧的值并按照顺序赋给等号左侧,却并没有临时保存等号左侧的地址。
因此,如果遇到链表、树等,需要同时赋值并且等号左侧包含取地址的变量(即带点号,如.next,.val)时,应当将取地址的变量放在比被取地址的变量前面的位置(如a.next, a;再如a.next.next, a.next)。当然如果实在分不清的话,分别赋值也是一个方法。