你所不知道的python--2

Interesting in python(2)


brackets,Multiplication sign,backslash,Equal sign,Quotation marks

括號,乘號,反斜杠,判等號,引號

小括號與中括號

is not and is (not ...)

@python 3.6.7

this = 'this'

print(this is not None)  # True
print(this is (not None))  #False

??上面應該很好理解,加了括號的not None is True

列表生成式與生成器表達式

@python3.6.7


list1 = [1, 2, 3]
t1 = (x for x in list1 if list1.count(x) > 0)  # iterator
list1 = [4, 2, 5]
print(list(t1))
# result
# [2]


list2 = [1, 2, 3]
t2 = [x for x in list2 if list2.count(x) > 0]  # list
list2 = [4, 2, 5]
print(t2)
# result
# [1, 2, 3]

??在上面中代碼中,我們對列表list1,list2分別進行生成器操作和列表生成后都立馬進行了重新賦值,但生成器的結果好像有點出乎意料。
??這是因為在生成器表達式中,in子句在聲明時執行,所以用來比較的x還是1,2,3;而if條件子句則在運行時執行,所以此時條件判斷中list1已經變成了[4,2,5],能夠判斷成功的就只有2了,而在列表生成式中則不受影響。

??另外一種情況:

@python 3.6.7

list1 = [1, 2, 3]
t1 = (x for x in list1)  # iterator
list1 = [1, 2, 3, 4]
print(list(t1))
# 兩個list1不是同一個對象
# result
# [1, 2, 3]


list2 = [1, 2, 3]
t2 = (x for x in list2)  # iterator
list2[:] = [1, 2, 3, 4]
print(list(t2))
# 由于切片操作賦值給相同的舊對象,兩個list2是同一個對象
# result
# [1, 2, 3, 4]


list2 = [1, 2, 3]
print(id(list2))
t2 = [x for x in list2]  # list
list2[:] = [1, 2, 3, 4]
print(id(list2))
print(list(t2))
# 兩個list2是同一個對象,但用列表生成式就不會O(∩_∩)O哈哈~
# result
# 139771935690440
# 139771935690440
# [1, 2, 3]

??這里好像與我們之前說的in在聲明的時候執行有點沖突,但其實不然,in確實是在聲明的時候就執行,這句話意思是上面代碼中賦值給x的是以前的list對象。所以當兩個list對象不同時,結果是原來list對象的值;而切片操作是賦值給原來的對象,in也操作原來的對象,所以就變成了賦值后的結果了。
??我們簡單總結一下,實際上如果用列表生成式,那么后一行代碼的操作不會影響它的執行結果,即使是改變同一個對象,因為列表生成式在這行代碼之后就已經完成;而生成器表達式的in子句會使用同一個對象,若改變同一對象就會對in造成影響,if條件子句則在執行時會受后面代碼改動的影響,不管是否改動的是同一對象。因此我們可以大膽的寫出以下代碼來進行驗證:

@python 3.6.7

old_list = [1, 2, 3]  # 1
t = (x for x in old_list if old_list.count(x) > 0)
old_list[:] = [4, 5, 6]  # 2
print(list(t))
# 因為切片,old_list原有對象被重新賦值,對象不變
# 所以in使用的是: # 2 注釋的old_list的值
# if進行判斷使用的也是: # 2 注釋的old_list的值
# 所以 result
# [4, 5, 6]

??所以當我們在使用生成器表達式時,如果為了節省變量名而隨意在生成器表達式后面改動變量原來的值就很容易造成一些意想不到的結果。但也不要因此就不使用生成器,畢竟對于數量龐大的列表改用生成器是非常劃算的,我們需要注意的只是命名規范和編碼習慣,不要輕易改變原來已經存在對象的值。

方便的乘號 *?

@python 3.6.7

single = [''] * 3  # single ['', '', '']
double = [single] * 2
# double [['', '', ''], ['', '', '']]

print(double[0][0])  # empty
double[0][0] = 'x'
print(double)
# result
# [['x', '', ''], ['x', '', '']]

??為啥明明我們只賦值了一個值,但是有兩個位置都有x呢?
??那是因為當我們使用乘號的進行快速創建列表時,實際上只是增加了doublesingle的引用,即double[0]double[1]引用的是同一個對象。

@python 3.6.7

single = [''] * 3
double = [single] * 2
print(id(double[0]), id(double[1]))
print(double[0] is double[1])
# result
# 140063679369736 140063679369736
# True

??所以毫無疑問賦值double[0][0]實際上也是在對double[1][0]進行操作。那么我們該如何消除這種影響,而做到我們真正想要的呢?下面有一種巧妙的辦法,就是不用中間變量進行引用。

@python 3.6.7

double = [[''] * 3 for _ in range(2)]
double[0][0] = 'x'
print(double)
# result
# [['x', '', ''], ['', '', '']]

反斜杠轉義和打印反斜杠

??眾所周知,反斜杠會對后面的字符進行轉移,所以\n代表換行,\r代表回車,那么如何打印字符串\n呢?再加上一個反斜杠是很好的選擇。

@python 3.6.7

newline = '\\n'
print(newline)
# result
# \n

??也可以使用下面的方法:

@python 3.6.7

newline = r'\n'
print(newline)
# result
# \n

??但是請注意不要這樣使用:

@python 3.6.7

print(r'\n\')  # SyntaxError

??因為在以r開頭的原始字符串中,解釋器改變了反斜杠會解釋后面一個字符的行為,取而代之的是直接放行反斜杠后面的一個字符,所以上面的最后一個單引號被視為要打印的一部分。如果非要這樣使用,正確的寫法應該是這樣的:

@python 3.6.7

print(r'\n\'')  # 再添加一個單引號
# result
# \n\'

小心運算符的優先級

@python 3.6.7

x = True
y = False

print(not x == y)  # True
print(x == not y)  # SyntaxError

??因為在python中==運算符的優先級要高于not運算符。所以not x == y等價于not (x == y)True;而x == not y等價于(x == not) y所以語法錯誤。

是拼接還是注釋

??我們都知道python多行注釋以三個引號為標記,但有些時候這只是字符串拼接。

@python 3.6.7
"""This is comment."""

print('''hello''')  # hello
print("""hello again""")  # hello again


print('hello''')  # hello
print("hello again""")  # hello again


print('''hello')  # SyntaxError

print("""hello again")  # SyntaxError

??如果你的編輯器有代碼高亮,實際上你已經可以看到不同之處。三個引號在前,那么解釋器會試圖再尋找三個相同的引號作為定界符,將其視為注釋或者可打印的字符串。而如果三個引號在后,實際上是隱式的字符串連接,'hello'''意味著'hello' '',拼接一個空字符串,因此可以正確打印。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 官網 中文版本 好的網站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,438評論 0 5
  • 包(lib)、模塊(module) 在Python中,存在包和模塊兩個常見概念。 模塊:編寫Python代碼的py...
    清清子衿木子水心閱讀 3,833評論 0 27
  • 不是所有拌嘴都是嘈雜 ■ 阿桂(山東) 還在和媳婦小聲地拌著嘴 因發燒而鬧騰不已的小家伙卻安靜下來 睡著...
    山東阿桂閱讀 311評論 2 7
  • 為什么說react里面的數據發生改變,其頁面顯示也會改變? 這是因為數據的改變,會引起react里面的state發...
    南藍NL閱讀 390評論 0 1
  • 在我所了解的小動物中,就是蜘蛛最聰明了,他的那種敏捷優美的動作讓我難以形容,他的那種迅速讓我難以置言。 蜘蛛的頭與...
    池有杰閱讀 491評論 0 1