
5.1 再談 print 和 import
5.1.1 打印多個參數(shù)
print可用于打印多個表達式,條件是用逗號分隔它們。如果需要,可自定義分隔符。還可自定義結(jié)束字符串,以替換默認的換行符。
>>> print("I", "wish", "to", "register", "a", "complaint", sep="_") I_wish_to_register_a_complaint
print('Hello', end='~')
print('world!')
Hello~world!
5.1.2 導(dǎo)入時重命名
在語句末尾添加as子句并指定別名。
>>> import math as foobar
>>> foobar.sqrt(4)
2.0
5.2 賦值魔法
5.2.1 序列解包
可同時(并行)給多個變量賦值。
>>> x, y, z = 1, 2, 3
>>> print(x, y, z)
1 2 3
還可交換多個變量的值
>>> x,y,z = y,z,x
>>> x,y,z
(2, 3, 1)
這里執(zhí)行的操作稱為序列解包(或可迭代對象解包):將一個序列(或任何可迭代對象)解包,并將得到的值存儲到一系列變量中。解包的序列包含的元素個數(shù)必須與你在等號左邊列出的目標個數(shù)相同,否則Python將引發(fā)異常。
可使用星號運算符(*)來收集多余的值,這樣無需確保值和變量的個數(shù)相同。還可將帶星號的變量放在其他位置。賦值語句的右邊可以是任何類型的序列, 但帶星號的變量最終包含的總是一個列表。 在變量和值的個數(shù)相同時亦如此。
>>> a, b, *rest = [1, 2, 3, 4]
>>> rest
[3, 4]
>>> a, *b, c = "abc"
>>> a, b, c
('a', ['b'], 'c')
5.2.2 鏈式賦值
多個變量關(guān)聯(lián)同一個值:
x = y = somefunction()
5.2.3 增強賦值
增強賦值,適用于所有標準運算符,如+=、*=、/=、%=等,也可以用于其他數(shù)據(jù)類型。
>>> fnord = 'foo'
>>> fnord += 'bar'
>>> fnord *= 2
>>> fnord
'foobarfoobar'
5.3 代碼塊:縮進的樂趣
代碼塊是一組語句,是通過縮進代碼(即在前面加空格)來創(chuàng)建的。在Python中,使用冒號:指出接下來是一個代碼塊,并將該代碼塊中的每行代碼都縮進相同的程度。
5.4 條件和條件語句
5.4.1 這正是布爾值的用武之地
下面的值都將被解釋器視為假:False``None``0``""``()``[]``{}其他值都為真。不需要顯示轉(zhuǎn)換。
5.4.2 有條件地執(zhí)行和 if 語句
if語句,如果條件為真,就執(zhí)行后續(xù)代碼塊;如果條件為假,就不執(zhí)行。
name = input("What's your name")
if name.endswith('Gumby'):
print('Hello, Mr.Gumby')
5.4.3 else 子句
可使用else子句增加一種選擇,
name = input("What's your name")
if name.endswith('Gumby'):
print('Hello, Mr.Gumby')
else:
print('Hello, stranger')
條件表達式(相當于三目運算符):
print('Hello, Mr.Gumby') if name.endswith('Gumby') else print('Hello, stranger')
5.4.4 elif 子句
elif是else if的縮寫,由一個if子句和一個else子句組合而成,也就是包含條件的else子句。
num = int(input('Enter a number: '))
if num > 0:
print('The number is positive')
elif num < 0:
print('The number is negative')
else:
print('The number is zero')
5.4.6 更復(fù)雜的條件
1. 比較運算符
| 表 達 式 | 描 述 |
|---|---|
| x == y | x等于y |
| x < y | x小于y |
| x > y | x大于y |
| x >= y | x大于或等于y |
| x <= y | x小于或等于y |
| x != y | x不等于y |
| x is y | x和y是同一個對象 |
| x is not y | x和y是不同的對象 |
| x in y | x是容器(如序列)y的成員 |
| x not in y | x不是容器(如序列)y的成員 |
Python也支持鏈式比較:可同時使用多個比較運算符,如0 < age < 100。
相等運算符:確定兩個對象是否相等,可使用比較運算符,用兩個等號(==)表示
is:相同運算符:is檢查兩個對象是否相同,是否是同一個對象。不要將is用于數(shù)和字符串等不可變的基本值。鑒于Python在內(nèi)部處理這些對象的方式,這樣做的結(jié)果是不可預(yù)測的。
in:成員資格運算符
字符串和序列的比較:字符串是根據(jù)字符的字母排列順序進行比較的。
>>> "alpha" < "beta"
True
>>> [1, 2] < [2, 1]
True
>>> [2, [1, 4]] < [2, [1, 5]]
True
2. 布爾運算符
布爾運算符包括and,or和not。通過使用這三個運算符,能以任何方式組合真值。布爾運算符是短路邏輯。
表達式x and y,如果x為假,這個表達式將返回x,否則返回y。
表達式x or y中,如果x為真,就返回x,否則返回y。
5.4.7 斷言
關(guān)鍵字assert可要求某些條件得到滿足(如核實函數(shù)參數(shù)滿足要求或為初始測試和調(diào)試提供幫助),還可在條件后面添加一個字符串,對斷言做出說明。
>>> age = 10
>>> assert 0 < a < 100
>>> age = -1
>>> assert 0 < age < 100, 'The age must be realistic'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: The age must be realistic
5.5 循環(huán)
5.5.1 while 循環(huán)
while語句用于循環(huán)
name = ''
while not name:
name = input('Please enter your name: ')
print('Hello, {}!'.format(name))
5.5.2 for 循環(huán)
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in numbers:
print(number)
Python提供了一個創(chuàng)建范圍的內(nèi)置函數(shù)。
>>> range(0, 10)
range(0, 10)
>>> list(range(0, 10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in range(1,101):
print(number)
5.5.3 迭代字典
要遍歷字典的所有關(guān)鍵字,可像遍歷序列那樣使用普通的for語句。
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print(key, 'corresponds to', d[key])
for key, value in d.items():
print(key, 'corresponds to', value)
5.5.4 一些迭代工具
1. 并行迭代
并行迭代工具是內(nèi)置函數(shù)zip,它將兩個序列“縫合”起來,并返回一個由元組組成的序列。返回值是一個適合迭代的對象,要查看其內(nèi)容,可使用list將其轉(zhuǎn)換為列表。當序列的長度不同時,函數(shù)zip將在最短的序列用完后停止。
names = ['anne', 'beth', 'george', 'damon']
ages = [12, 45, 32, 102]
print(list(zip(names, ages)))
for name, age in zip(names, ages):
print(name, 'is', age, 'years old')
print(list(zip(range(10), range(4), range(100))))
[('anne', 12), ('beth', 45), ('george', 32), ('damon', 102)]
anne is 12 years old
beth is 45 years old
george is 32 years old
damon is 102 years old
[(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3)]
2. 迭代時獲取索引
一種方法是加入一個index變量,類似于原來的:for(i = 0;i < str.length(); i++)。
index = 0
for string in strings:
if 'xxx' in string:
strings[index] = '[censored]'
index += 1
另一種方案是采用內(nèi)置函數(shù)enumrate。這個函數(shù)讓你能夠迭代索引-值對,其中的索引是自動提供的。
for index, string in enumerate(strings):
if 'xxx' in string:
strings[index] = '[censored]'
3. 反向迭代和排序后再迭代
函數(shù)reverse和sorted可用于任何序列或可迭代的對象,且不就地修改對象,而是返回反轉(zhuǎn)和排序后的版本。
>>> sorted('Hello, world!')
[' ', '!', ',', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(reversed('Hello, world!'))
['!', 'd', 'l', 'r', 'o', 'w', ' ', ',', 'o', 'l', 'l', 'e', 'H']
sorted返回一個列表,reversed返回一個可迭代對象。要按字母表排序,可先轉(zhuǎn)換為小寫。為此,可將sort或sorted的key參數(shù)設(shè)置為str.lower。例如,sorted("aBc", key=str.lower)返回['a', 'B', 'c']。
5.5.5 跳出循環(huán)
- break 要跳出循環(huán),可使用break。
- continue 它結(jié)束當前迭代,并跳到下一次迭代開頭。
5.5.6 循環(huán)中的 else 子句
如何判斷循環(huán)是提前結(jié)束還是正常結(jié)束的,之前可在循環(huán)開始前定義一個布爾變量并將其設(shè)置為False,再在跳出循環(huán)時將其設(shè)置為True。python中更簡單的辦法是在循環(huán)中添加一條else子句,它僅在沒有調(diào)用break時才執(zhí)行。無論是在for循環(huán)還是while循環(huán)中,都可使用continue、break和else子句。
from math import sqrt
for n in range(99, 81, -1):
root = sqrt(n)
if root == int(root):
print(n)
break
else:
print("Didn't find it!")
5.6 簡單推導(dǎo)
列表推導(dǎo)是一種從其他列表創(chuàng)建列表的方式, 類似于數(shù)學(xué)中的集合推導(dǎo)。
>>> [x * x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10) if x % 3 == 0]
[0, 9, 36, 81]
>>> [(x, y) for x in range(3) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)
使用圓括號代替方括號并不能實現(xiàn)元組推導(dǎo),而是將創(chuàng)建生成器,然而,可使用花括號來執(zhí)行字典推導(dǎo)。
squares = {i:"{} squared is {}".format(i, i**2) for i in range(10)}
print(squares[8])
8 squared is 64
5.7 三人行
5.7.1 什么都不做
pass語句可以作為占位符。
5.7.2 使用 del 刪除
del語句刪除對象名稱
5.7.3 使用 exec 和 eval 執(zhí)行字符串及計算其結(jié)果
函數(shù)exec將字符串作為代碼執(zhí)行。
str = 'print("Hello world")'
exec(str)
Hello world
在大多數(shù)情況下,還應(yīng)向它提供一個字典以充當命名空間,防止代碼污染命名空間。可向exec提供兩個命名空間:一個全局的和一個局部的。提供的全局命名空間必須是字典,而提供的局部命名空間可以是任何映射。這一點也適用于eval。
x = 10
expr = """
z = 30
sum = x + y + z
print(sum)
"""
def func():
y = 20
exec(expr)
exec(expr,{'x': 1, 'y': 2, 'z': 3})
exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
func()
60
33
34
eval是一個類似于exec的內(nèi)置函數(shù)。exec執(zhí)行一系列Python語句,而eval計算用字符串表示的Python表達式的值,并返回結(jié)果
- eval()函數(shù)只能計算單個表達式的值,而exec()函數(shù)可以動態(tài)運行代碼段。
- eval()函數(shù)可以有返回值,而exec()函數(shù)返回值永遠為None。