python基礎(chǔ)-1

本教程基于Python 3,參考 A Byte of Python v1.92(for Python 3.0) 以及廖雪峰python教程

1第一個(gè)python程序

1.1 python的三種執(zhí)行方式

1.在Python交互式命令行下,可以直接輸入代碼,然后執(zhí)行,并立刻得到結(jié)果。交互式環(huán)境會(huì)把每一行Python代碼的結(jié)果自動(dòng)打印出來(lái)。

看到>>>即是在Python交互式環(huán)境下

2.用python運(yùn)行Python代碼
文件必須以.py結(jié)尾。此外,文件名只能是英文字母、數(shù)字和下劃線的組合。
例如寫一個(gè)calc.py的文件,在命令行模式下執(zhí)行:

$python calc.py

3.用./直接運(yùn)行py文件
方法:
在.py文件的第一行加上一個(gè)特殊的注釋 #!/usr/bin/env python3
源文件的頭兩個(gè)字符是#! ,稱之為組織行。這行告訴你的Linux/Unix 系統(tǒng)當(dāng)你執(zhí)行
你的程序的時(shí)候,它應(yīng)該運(yùn)行哪個(gè)解釋器。env 程序用于反過(guò)來(lái)尋找運(yùn)行程序的Python 解釋器

#!/usr/bin/env python3  
print('hello, world')

然后,通過(guò)命令給hello.py以執(zhí)行權(quán)限:

$ chmod a+x hello.py

最后,在終端執(zhí)行

./hello.py  //輸出hello, world

1.2 python的兩種注釋方式

#單行注釋
'''
三引號(hào)多行注視
'''

1.3 python輸入與輸出

輸出

用print()在括號(hào)中加上字符串,就可以向屏幕上輸出指定的文字。
print()會(huì)依次打印每個(gè)字符串,遇到逗號(hào)“,”會(huì)輸出一個(gè)空格

>>>print('1024 * 768 = ', 1024*768) //1024 * 768 =  786432
>>>number = 555
>>>print(number) //555
>>>print(type(number)) //<class 'int'>
輸入

input(),可以讓用戶輸入字符串,并存放到一個(gè)變量里。比如輸入用戶的名字:
輸入的值就會(huì)存放到name變量里

>>> name = input()
Michael

input()返回的數(shù)據(jù)類型是str
讀取文本文件時(shí),返回的數(shù)據(jù)類型也是str。由于str不能直接和整數(shù)比較,必須先把str轉(zhuǎn)換成整數(shù)。Python提供了int()函數(shù)來(lái)將str轉(zhuǎn)換成整數(shù)

s = input('birth: ')
birth = int(s) //int()函數(shù)將str轉(zhuǎn)換成整數(shù)
if birth < 2000:
    print('00前')
else:
    print('00后')

但當(dāng)輸入abc時(shí),會(huì)得到錯(cuò)誤信息,int()函數(shù)發(fā)現(xiàn)一個(gè)字符串并不是合法的數(shù)字時(shí)就會(huì)報(bào)錯(cuò),程序就退出了。

Python也提供了str()函數(shù)來(lái)將其他類型轉(zhuǎn)換成字符串
類似還有float()等方法

eight = 8
str_eight = str(eight)
print(type(str_eight)) //<class 'str'>

1.4 python語(yǔ)法

1.Python 沒(méi)有強(qiáng)制性語(yǔ)句終止字符,使用4個(gè)空格的縮進(jìn)來(lái)組織代碼塊,(每一行都是一個(gè)語(yǔ)句,當(dāng)語(yǔ)句以冒號(hào):結(jié)尾時(shí),縮進(jìn)的語(yǔ)句視為代碼塊。同一層次的語(yǔ)句必須有相同的縮進(jìn)。
縮進(jìn)的壞處是“復(fù)制-粘貼”功能失效了,當(dāng)重構(gòu)代碼時(shí),粘貼過(guò)去的代碼必須重新檢查縮進(jìn)是否正確。

# print absolute value of an integer:
a = 100
if a >= 0:
    print(a)
else:
    print(-a)

2.Python程序是大小寫敏感

2 python基礎(chǔ)

2.1 數(shù)

在Python 中數(shù)的類型有三種——整數(shù)、浮點(diǎn)數(shù)復(fù)數(shù)。
? 2 是一個(gè)整數(shù)的例子。Python可以處理任意大小的整數(shù),1,100,-8080,0,0xff00(十六進(jìn)制),0xa5b4c3d2(十六進(jìn)制)
? Python的浮點(diǎn)數(shù)也沒(méi)有大小限制,但是超出一定范圍就直接表示為inf
1.23,3.14,-9.01,對(duì)于很大或很小的浮點(diǎn)數(shù),就必須用科學(xué)計(jì)數(shù)法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012可以寫成1.2e-5。
? (-5+4j) 和(2.3-4.6j) 是復(fù)數(shù)的例子。

2.2 字符串

字符串是字符的序列,是以單引號(hào)'或雙引號(hào)"括起來(lái)的任意文本,比如'abc',"xyz"等等。
在Python 中沒(méi)有單獨(dú)的char 數(shù)據(jù)類型。記住單引號(hào)和雙引號(hào)是一樣的。

單引號(hào)

你可以用單引號(hào)指定字符串,如’Quote me on this’。所有的空白,即空格和制表符都照原樣保留。

雙引號(hào)

在雙引號(hào)中的字符串與單引號(hào)中的字符串的使用完全相同,例如"What’s your name?" 。
請(qǐng)注意,''或""本身只是一種表示方式,不是字符串的一部分。如果'本身也是一個(gè)字符,那就可以用""括起來(lái),比如"I'm OK"包含的字符是I,',m,空格,O,K這6個(gè)字符。 還可以采用利用轉(zhuǎn)義符'I\'m OK'表示

三引號(hào)

利用三引號(hào)(''' ),用來(lái)輸入多行文本,也就是說(shuō)在三引號(hào)之間輸入的內(nèi)容將被原樣保留,之中的單號(hào)和雙引號(hào)不用轉(zhuǎn)義,其中的不可見字符比如/n和/t都會(huì)被保留,這樣的好處是你可以替換一些多行的文本。

'''This is a multi-line string. This is the first line.
This is the second line.
 "What's your name?," I asked.
He said "Bond, James Bond."
'''
轉(zhuǎn)義序列

轉(zhuǎn)義字符\可以轉(zhuǎn)義很多字符,比如\n表示換行,\t表示制表符,字符\本身也要轉(zhuǎn)義,所以\\表示的字符就是\
如果字符串內(nèi)部有很多換行,用\n寫在一行里不好閱讀,為了簡(jiǎn)化,Python允許用'''...'''的格式表示多行內(nèi)容

>>> print('''line1
... line2
... line3''')
line1
line2
line3
自然字符串

通過(guò)在字符串前面附加r 或R 來(lái)指定自然字符串,省去了使用大量轉(zhuǎn)義序列 \ 的麻煩。例如后向引用符可以寫成’\\1’r’\1’。在正則表達(dá)式中推薦使用r。

字符串是不可變的

這意味著一個(gè)字符串一旦創(chuàng)建,就不能在改變它。

字符串運(yùn)算
# 字符串加法
"Hello " + "world!"  # => "Hello world!"
# 字符串加法,可以不使用 '+'
"Hello " "world!"  # => "Hello world!"
#一個(gè)字符串可以被認(rèn)為是一個(gè)字符列表
"This is a string"[0]  # => 'T'
# 可以獲得字符的長(zhǎng)度(如果有空格,字符的長(zhǎng)度將包含空格)
len("This is a string")  # => 16
len("I'm OK") # => 6, I,',m,空格,O,K這6個(gè)字符

2.3 布爾值bool

只有True、False兩種值

#bool值的運(yùn)算
>>>True and False  #False
>>>False or True  # True
#對(duì)整數(shù)的bool運(yùn)算
0 and 2  # 0
-5 or 0  #-5
0 == False  #True
2 == True  #False
1 == True  #True
#bool值的not運(yùn)算
not True  #False
not False  #True
>>> cat = True
>>> dog = False
>>> print(type(cat))
<class 'bool'>

>>> print(9!=9)
False
>>> print('abc' == 'abc')
True
>>> print(['asp', 'php'] == ['asp', 'php'])
True

bool()函數(shù)

#除了以下兩種情況,所有其他值是True(即使用bool()函數(shù)返回True)
bool(0)#=> False
bool(“”)#=> False

2.4 變量

變量是你的計(jì)算機(jī)中存儲(chǔ)信息的一部分內(nèi)存。與字面意義上的常量不同,你需要能夠訪問(wèn)這些變量的方法,因此要給變量命名。
Python中,等號(hào)=是賦值語(yǔ)句,可以把任意數(shù)據(jù)類型賦值給變量,同一個(gè)變量可以反復(fù)賦值,而且可以是不同類型的變量,例如:

a = 123 # a是整數(shù)
print(a)
a = 'ABC' # a變?yōu)樽址?print(a)

這種變量本身類型不固定的語(yǔ)言稱之為動(dòng)態(tài)語(yǔ)言,與之對(duì)應(yīng)的是靜態(tài)語(yǔ)言。靜態(tài)語(yǔ)言在定義變量時(shí)必須指定變量類型,如果賦值的時(shí)候類型不匹配,就會(huì)報(bào)錯(cuò)。例如Java

標(biāo)識(shí)符命名規(guī)則

1.首字符為字母或下劃線,所以以數(shù)字開頭無(wú)效
2.除了首字符以外的其余字符可以是字母、下劃線或注釋。
3.標(biāo)識(shí)符名稱對(duì)大小寫敏感。

#變量名的書寫規(guī)則 (單詞之間通過(guò)下橫線連接)
days = 365
days_1 = 365
days_2 = 365
number_of_days = 365
理解變量在計(jì)算機(jī)內(nèi)存中的表示

a = 'ABC'時(shí),Python解釋器干了兩件事情:
1.在內(nèi)存中創(chuàng)建了一個(gè)'ABC'的字符串;
2.在內(nèi)存中創(chuàng)建了一個(gè)名為a的變量,并把它指向'ABC'。

也可以把一個(gè)變量a賦值給另一個(gè)變量b,這個(gè)操作實(shí)際上是把變量b指向變量a所指向的數(shù)據(jù)

a = 'ABC'
b = a
a = 'XYZ'
print(b) #ABC

2.5 對(duì)象

Python 是完全面向?qū)ο蟮?,在某種意義上,任何東西都被作為對(duì)象,包括數(shù)字、字符串和函數(shù)。
我們不會(huì)說(shuō)“某某東西”,我們會(huì)說(shuō)“某個(gè)對(duì)象”。

2.6 常量的習(xí)慣性寫法

Python中,通常用全部大寫的變量名表示常量:

PI = 3.14159265359

但事實(shí)上PI仍然是一個(gè)變量,Python根本沒(méi)有任何機(jī)制保證PI不會(huì)被改變,所以,用全部大寫的變量名表示常量只是一個(gè)習(xí)慣上的用法,如果你一定要改變變量PI的值,也沒(méi)人能攔住你。

3 操作符和表達(dá)式

3.1 特別說(shuō)明

兩種除法運(yùn)算
1.一種除法是/,計(jì)算結(jié)果是浮點(diǎn)數(shù),即使是兩個(gè)整數(shù)恰好整除,結(jié)果也是浮點(diǎn)數(shù)

>>> 10 / 3
3.3333333333333335
>>> 9 / 3
3.0

2.還有一種除法是//,稱為地板除,計(jì)算結(jié)果是整數(shù),即使除不盡。

>>> 10 // 3
3

因?yàn)?/除法只取結(jié)果的整數(shù)部分,所以Python還提供一個(gè)余數(shù)運(yùn)算,可以得到兩個(gè)整數(shù)相除的余數(shù):

>>> 10 % 3
1

指數(shù)運(yùn)算
python中使用**表示指數(shù)運(yùn)算

num = 10
print(num**2) //100

3.2 優(yōu)先級(jí)

下面這個(gè)表給出Python 的運(yùn)算符優(yōu)先級(jí),從最低的優(yōu)先級(jí)到最高的優(yōu)先級(jí)。這意味著在一個(gè)表達(dá)式中, Python 會(huì)首先計(jì)算表中較下面的運(yùn)算符,然后在計(jì)算列在表上部的運(yùn)算符,但建議使用圓括號(hào)來(lái)分組運(yùn)算符和操作數(shù)。


3.3 字符串和編碼

Python源代碼也是一個(gè)文本文件,所以,當(dāng)你的源代碼中包含中文的時(shí)候,在保存源代碼時(shí)需要?jiǎng)?wù)必指定保存為UTF-8編碼(確保文本編輯器正在使用UTF-8 without BOM編碼)。
當(dāng)Python解釋器讀取源代碼時(shí),為了讓它按UTF-8編碼讀取,我們通常在文件開頭寫上這兩行:

#!/usr/bin/env python3 //告訴Linux/OS X系統(tǒng),這是一個(gè)Python可執(zhí)行程序
# -*- coding: utf-8 -*-  //告訴Python解釋器,按照UTF-8編碼讀取源代碼,否則,你在源代碼中寫的中文輸出可能會(huì)有亂碼。

3.4 格式化

如何輸出格式化的字符串。我們經(jīng)常會(huì)輸出類似'親愛的xxx你好!你xx月的話費(fèi)是xx,余額是xx'之類的字符串,而xxx的內(nèi)容都是根據(jù)變量變化的。
Python中,%運(yùn)算符就是用來(lái)格式化字符串的。在字符串內(nèi)部,%s表示用字符串替換,%d表示用整數(shù)替換,有幾個(gè)%?占位符,后面就跟幾個(gè)變量或者值,順序要對(duì)應(yīng)好。如果只有一個(gè)%?,括號(hào)可以省略。
常見的占位符有:

%d  整數(shù)
%f  浮點(diǎn)數(shù)
%s  字符串
%x  十六進(jìn)制整數(shù)
>>> 'Hello, %s' % 'world' //'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000) //'Hi, Michael, you have $1000000.'
>>> '%2d-%02d' % (3, 1) //' 3-01' 指定是否補(bǔ)0和整數(shù)與小數(shù)的位數(shù):
>>> '%.2f' % 3.1415926 //'3.14'指定是否補(bǔ)0和整數(shù)與小數(shù)的位數(shù):
>>> 'growth rate: %d %%' % 7  // 'growth rate: 7 %' 若字符串里面的%是一個(gè)普通字符,就需要轉(zhuǎn)義,用%%來(lái)表示一個(gè)%:

新的格式化方法:format方法(首選)
format 方法利用參變量的值代替格式符

age = 25
name = 'Swaroop'
print('{0} is {1} years old'.format(name, age))
print('Why is {0} playing with that python?'.format(name))
輸出:
Swaroop is 25 years old
Why is Swaroop playing with that python?

運(yùn)行原理:
一個(gè)字符串能使用確定的格式,隨后,可以調(diào)用format 方法來(lái)代替這些格式,參數(shù)要與format 方法的參數(shù)保持一致。
觀察首次使用0 的地方,這與format 方法的第一個(gè)參變量name 相一致。類似地,第二個(gè)格式1 與format 方法的第二個(gè)參變量age 相一致。

"{} is a {}".format("This", "placeholder")
"{0} can be {1}".format("strings", "formatted")
# 可以使用keywords如果不想數(shù)數(shù)字
"{name} wants to eat {food}".format(name="Bob", food="lasagna")

3.5 None(None是一個(gè)對(duì)象)

#不能使用相等的“==”符號(hào)將對(duì)象與None進(jìn)行比較,而要使用is
"etc" is None  # => False
None is None  # => True

4 控制流

在到目前為止我們所見到的程序中,總是有一系列的語(yǔ)句,Python 忠實(shí)地按照它們的順序執(zhí)行它們。如果想要改變語(yǔ)句流的執(zhí)行順序,需要通過(guò)控制流語(yǔ)句實(shí)現(xiàn)。在Python 中有三種控制流語(yǔ)句——if、for 和while 。

4.1 if 語(yǔ)句

if 語(yǔ)句用來(lái)檢驗(yàn)一個(gè)條件,如果條件為真,我們運(yùn)行一塊語(yǔ)句(稱為if-塊),否則我們處理另外一塊語(yǔ)句(稱為else-塊)。else 子句是可選的。

if語(yǔ)句的完整形式

if <條件判斷1>:        //注意每一個(gè)語(yǔ)句之后的冒號(hào):
    <執(zhí)行1>
elif <條件判斷2>:
    <執(zhí)行2>
elif <條件判斷3>:
    <執(zhí)行3>
else:
    <執(zhí)行4>

給C/C++ 程序員的注釋:
在Python 中沒(méi)有switch 語(yǔ)句。你可以使用if..elif..else 語(yǔ)句來(lái)完成同樣的工作(在某些場(chǎng)合,使用字典會(huì)更加快捷。)

也可以使用

if <條件判斷1>:       
    <執(zhí)行1>

或者

if <條件判斷1>:       
    <執(zhí)行1>
else:
    <執(zhí)行4>

if可以用作表達(dá)式,相當(dāng)于C的'?:'三元運(yùn)算符

"yahoo!" if 3 > 2 else 2  # => "yahoo!"
"yahoo!" if 3 < 2 else 2  # =>  2

if語(yǔ)句例子

age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:        
    print('your age is', age)
    print('teenager')
輸出:
your age is 3
teenager

if語(yǔ)句的執(zhí)行特點(diǎn)
if語(yǔ)句是從上往下判斷,如果在某個(gè)判斷上是True,把該判斷對(duì)應(yīng)的語(yǔ)句執(zhí)行后,就忽略掉剩下的elif和else

age = 20
if age >= 6:
    print('teenager') //此處判斷為true,就忽略掉剩下的elif和else
elif age >= 18:
    print('adult')
else:
    print('kid')

if判斷條件的簡(jiǎn)寫

if x:
    print('True')

練習(xí)

小明身高1.75,體重80.5kg。請(qǐng)根據(jù)BMI公式(體重除以身高的平方)幫小明計(jì)算他的BMI指數(shù),并根據(jù)BMI指數(shù):
低于18.5:過(guò)輕
18.5-25:正常
25-28:過(guò)重
28-32:肥胖
高于32:嚴(yán)重肥胖

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

weight = input('weight: ')
height = input('height: ')
weight = float(weight)
height = float(height)
BMI = weight/(height*height)
if BMI < 18.5:
    print('過(guò)輕')
elif 18.5< BMI < 25:
    print('正常')
elif 25< BMI < 28:
    print('肥胖')
else:
    print('嚴(yán)重肥胖')

4.2 while循環(huán)

只要在一個(gè)條件為真的情況下, 就不斷循環(huán),條件不滿足時(shí)退出循環(huán)。while 語(yǔ)句有一個(gè)可選的else 從句。

while <條件判斷1>:       
    <執(zhí)行1>
else:
    <執(zhí)行2>

計(jì)算100以內(nèi)所有奇數(shù)之和

sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum) //2500

給C/C++ 程序員的注釋:
記得while 循環(huán)可以有else 語(yǔ)句。

4.3 for...in 循環(huán)

for..in 是另外一個(gè)循環(huán)語(yǔ)句,它在一序列的對(duì)象上迭代,即逐一使用序列中的每個(gè)項(xiàng)目??梢杂糜谝来伟裭ist或tuple中的每個(gè)元素迭代出來(lái)。
for x in ...循環(huán)就是把每個(gè)元素代入變量x,然后執(zhí)行縮進(jìn)塊的語(yǔ)句。else 部分是可選的。如果包含else ,它總是在for 循環(huán)結(jié)束后執(zhí)行一次,除非遇到break 語(yǔ)句。

names = ['Michael', 'Bob', 'Tracy']
for name in names:  //for 自定義元素別名 in 要遍歷的list
    print(name) //循環(huán)體中的內(nèi)容,需要四個(gè)空格的縮進(jìn)

輸出:依次打印list names中的每一個(gè)元素
Michael
Bob
Tracy

計(jì)算1-10的整數(shù)之和

sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    sum = sum + x
print(sum) //無(wú)縮進(jìn),表示不在循環(huán)體中。輸出55

通過(guò)range()函數(shù)生成整數(shù)序列

for x in range(1,5):
    print(x)
else:
    print ( 'The for loop is over' )
輸出:
1
2
3
4
The for loop is over

range(1,5) 給出序列[1, 2, 3, 4]。range 的步長(zhǎng)默認(rèn)為1。如果我們?yōu)閞ange 提供第三個(gè)數(shù),那么它將成為步長(zhǎng)。例如,range(1,5,2) 給出[1,3]

>>> list(range(5)) //range(5)生成的序列是從0開始小于5的整數(shù),通過(guò)list()函數(shù)可以轉(zhuǎn)換為list
[0, 1, 2, 3, 4]

for i in range(10): 
     print(i) //依次打印0,1,2,3,4,5,6,7,8,9

計(jì)算1-100的整數(shù)之和

sum=0;
for x in range(101):  //range(101)可以生成0-100的整數(shù)序列
    sum +=x
print(sum) //5050

遍歷list中的所有元素

s = [['asp', 'php'],['pp','java']]
for aa in s:
    for bb in aa:
        print(bb)
輸出:
asp
php
pp
java

練習(xí)
請(qǐng)利用循環(huán)依次對(duì)list中的每個(gè)名字打印出Hello, xxx!:

L = ['Bart', 'Lisa', 'Adam']
for name in L:
    print('hello,'+name+'!')

輸出:
hello,Bart!
hello,Lisa!
hello,Adam!

給C/C++程序員的注釋:
Python 的for 循環(huán)從根本上不同于C/C++ 的for 循環(huán)。
在C/C++ 中,如果你想要寫for (int i = 0; i < 5; i++),那么用Python ,你寫成for i in range(0,5)。你會(huì)注意到, Python 的for 循環(huán)更加簡(jiǎn)單、明白、不易出錯(cuò)。

4.4 break語(yǔ)句

break可用于for 或while 循環(huán)中,用于提前終止循環(huán)語(yǔ)句。如果你從for 或while 循環(huán)中終止,任何對(duì)應(yīng)的循環(huán)else塊將不執(zhí)行。

n = 1
while n <= 100:
    if n > 10: # 當(dāng)n = 11時(shí),條件滿足,執(zhí)行break語(yǔ)句
        break # break語(yǔ)句會(huì)結(jié)束當(dāng)前循環(huán)
    print(n)
    n = n + 1
print('END')   //打印出1~10后,緊接著打印END

4.5 continue

continue語(yǔ)句,跳過(guò)當(dāng)前的這次循環(huán),直接開始下一次循環(huán)。

n = 0
while n < 10:
    n = n + 1
    if n % 2 == 0: # 如果n是偶數(shù),執(zhí)行continue語(yǔ)句
        continue # continue語(yǔ)句會(huì)直接繼續(xù)下一輪循環(huán),后續(xù)的print()語(yǔ)句不會(huì)執(zhí)行
    print(n)

5 數(shù)據(jù)結(jié)構(gòu)

在Python 中有四種內(nèi)建的數(shù)據(jù)結(jié)構(gòu)—— 列表、元組、字典和集合

5.1 list列表

Python內(nèi)置的一種數(shù)據(jù)類型是列表:list。list是一種有序的集合,可以隨時(shí)添加和刪除其中的元素。
聲明list類型

classmates = []
print(type(classmates)) //<class 'list'>

創(chuàng)建list

>>> classmates = ['Michael', 'Bob', 'Tracy']  //創(chuàng)建一個(gè)list:
>>> classmates
['Michael', 'Bob', 'Tracy']

通過(guò)索引或切片獲取list中的值

>>> len(classmates) //輸出3 用len()函數(shù)可以獲得list中元素的個(gè)數(shù):
>>> classmates[0] //輸出'Michael' 用索引(從0開始)來(lái)訪問(wèn)list中每一個(gè)位置的元素
//當(dāng)索引超出了范圍時(shí),Python會(huì)報(bào)一個(gè)IndexError錯(cuò)誤,所以,要確保索引不要越界,記得最后一個(gè)元素的索引是len(classmates) - 1。
>>> classmates[-1] //可以用-1做索引,直接獲取最后一個(gè)元素
>>> classmates[-2] //以此類推,可以獲取倒數(shù)第2個(gè)

使用切片,取頭不取尾(所有對(duì)list的操作都會(huì)創(chuàng)建一個(gè)list的copy,對(duì)它進(jìn)行操作)
>>> month = [1,2,3,4,5,6,7,8,9,10,11,12]
>>> month[2:5]
[3, 4, 5]

>>> month[2:] //取到結(jié)尾
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

獲取索引為2倍數(shù)的元素
li = [1,2,3,4,5,6,7,8,9]
li[::2] #[1, 3, 5, 7, 9]

顛倒list
li[::-1] #[9, 8, 7, 6, 5, 4, 3, 2, 1]

獲取list的長(zhǎng)度(list中元素的個(gè)數(shù))
len(li) #9

插入&刪除&替換list中的元素

>>> classmates.append('Adam') //使用append往list中追加元素到末尾
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']

>>> classmates.insert(1, 'Jack') //用insert把元素插入到指定的位置
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']

>>> classmates.pop() //用pop()方法 刪除list末尾的元素
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']

>>> classmates.pop(1) //用pop(i)刪除指定位置的元素
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']

>>>del classmates[0] //使用“del”刪除列表中的任意元素

>>> classmates[1] = 'Sarah' //直接賦值給對(duì)應(yīng)的索引位置 替換元素
>>> classmates
['Michael', 'Sarah', 'Tracy']

for循環(huán)遍歷list元素&list元素排序

>>> shoplist = ['apple', 'mango', 'carrot', 'banana']
>>> for item in shoplist:
    print(item,end =' ')
輸出結(jié)果:
apple mango carrot banana   #print函數(shù)的end關(guān)鍵參數(shù)來(lái)表示以空格結(jié)束輸出,而不是通常的換行

>>> shoplist
['apple', 'mango', 'carrot', 'banana']
>>> shoplist.sort()
>>> shoplist
['apple', 'banana', 'carrot', 'mango']
#用sort 方法將列表進(jìn)行排序。理解這一方法影響了列表本身,沒(méi)有返回修改后的列表是重要的—— 這與字符串起作用的方式不同。
這就是我們所說(shuō)的列表是易變的,字符串是不可變的。

list里面的元素的數(shù)據(jù)類型也可以不同

L = ['Apple', 123, True]

list中的元素也可以是另一個(gè)list,比如:

>>> s = ['python', 'java', ['asp', 'php'], 'scheme']
>>> len(s) //注意s只有4個(gè)元素,其中s[2]又是一個(gè)list
4
>>> s[2]
['asp', 'php']
>>> s[2][1] //要拿到'php'可以寫s[2][1],s可以看成是一個(gè)二維數(shù)組
'php'

空的list的長(zhǎng)度為0:

>>> L = []
>>> len(L)
0

5.2 tuple元組

另一種有序列表叫元組:tuple。tuple和list非常類似,只不過(guò)元組tuple和字符串一樣是不可變的,一旦初始化就不能修改。
創(chuàng)建元組tuple

>>> classmates = ('Michael', 'Bob', 'Tracy') //對(duì)比創(chuàng)建list classmates = ['Michael', 'Bob', 'Tracy']

classmates這個(gè)tuple不能變了,它也沒(méi)有append(),insert()這樣的方法。其他獲取元素的方法和list是一樣的,你可以正常地使用classmates[0],classmates[-1],但不能賦值成另外的元素。
例子:

>>> zoo = ('python', 'elephant', 'penguin')
>>> len(zoo)
3
>>> new_zoo = ('monkey', 'camel', zoo)
>>> len(new_zoo)
3
>>> new_zoo
('monkey', 'camel', ('python', 'elephant', 'penguin'))
>>> new_zoo[2]
('python', 'elephant', 'penguin')
>>> new_zoo[2][2]
'penguin'

不可變的tuple有什么意義?
因?yàn)閠uple不可變,所以代碼更安全。如果可能,能用tuple代替list就盡量用tuple。

tuple的陷阱:含有1 個(gè)項(xiàng)目的元組
當(dāng)你定義一個(gè)tuple時(shí),在定義的時(shí)候,tuple的元素就必須被確定下來(lái)

>>> t = (1, 2) 
>>> t = () //定義一個(gè)空的tuple
>>> t = (1,) //只有1個(gè)元素的tuple定義時(shí)必須加一個(gè)逗號(hào),來(lái)消除歧義
>>> t = (1) //否則這樣定義的不是tuple,是1這個(gè)數(shù),因?yàn)槔ㄌ?hào)()既可以表示tuple,又可以表示數(shù)學(xué)公式中的小括號(hào),Python規(guī)定,這種情況按小括號(hào)進(jìn)行計(jì)算

一個(gè)“可變的”tuple

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t
('a', 'b', ['X', 'B']) 

tuple所謂的“不變”是說(shuō),tuple的每個(gè)元素,指向永遠(yuǎn)不變。即指向'a',就不能改成指向'b',指向一個(gè)list,就不能改成指向其他對(duì)象,但指向的這個(gè)list本身是可變的
所以,如果要?jiǎng)?chuàng)建一個(gè)內(nèi)容也不變的tuple,就必須保證tuple的每一個(gè)元素本身也不能變。

5.3 dict

使用if實(shí)現(xiàn)的字典

animals = ['cat','dog','rabbit']
if 'cat' in animals:
    print('cat found') #cat found

另一種字典方式

animals = ['cat','dog','rabbit']
cat_found = 'cat' in animals
print(cat_found) #True

Python內(nèi)置了字典:dict的支持,dict全稱dictionary,在其他語(yǔ)言中也稱為map,使用鍵-值(key-value)存儲(chǔ),具有極快的查找速度。注意,鍵必須是唯一的,就像如果有兩個(gè)人恰巧同名的話,你無(wú)法找到正確的信息。
所以只能使用不可變的對(duì)象(比如字符串)來(lái)作為字典的鍵,但可以把不可變或可變的對(duì)象作為字典的值。
鍵/值對(duì)用冒號(hào)分割,而各個(gè)對(duì)用逗號(hào)分割,所有這些都包括在花括號(hào)中。
記住字典中的鍵/值對(duì)是沒(méi)有順序的。如果你想要一個(gè)特定的順序,那么你應(yīng)該在使用前自己對(duì)它們排序。

通過(guò)dict實(shí)現(xiàn)一個(gè)“名字”-“成績(jī)”的對(duì)照表

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} //在初始化時(shí)就指定數(shù)據(jù)
>>> d['Michael']
95
>>> print(type(d))
<class 'dict'>

>>> d['Adam'] = 67  //使用索引操作符來(lái)尋址一個(gè)鍵并為它賦值,這樣就增加了一個(gè)新的鍵/值對(duì)
>>> d['Adam']
67

>>> d['Jack'] = 90  //一個(gè)key只能對(duì)應(yīng)一個(gè)value,多次對(duì)一個(gè)key放入value,后面的值會(huì)把前面的值沖掉
>>> d['Jack']
90
>>> d['Jack'] = 88
>>> d['Jack']
88

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85, 'Adam': 67, 'Jack': 88}
>>> del d['Michael']    #使用del刪除一個(gè)鍵值對(duì)
>>> d
{'Bob': 75, 'Tracy': 85, 'Adam': 67, 'Jack': 88}

使用字典的items 方法,來(lái)使用字典中的每個(gè)鍵/值對(duì)。
這會(huì)返回一個(gè)元組的列表,其中每個(gè)元組都包含一對(duì)項(xiàng)目—— 鍵與對(duì)應(yīng)的值。我們抓取這個(gè)對(duì),然后分別賦給for..in 循環(huán)中的變量name 和score 然后在for 塊中打印這些值。

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85, 'Adam': 67, 'Jack': 88}
>>> for name, score in d.items():
    print('{0}\'s score is {1}'.format(name, score))
輸出結(jié)果:   
Michael's score is 95
Bob's score is 75
Tracy's score is 85
Adam's score is 67
Jack's score is 88

檢驗(yàn)一個(gè)鍵/值對(duì)是否存在的兩種方法
方法一:使用in 操作符判斷key是否存在

>>> 'Michael' in s
True
>>> 'lucy' in s
False

方法二:通過(guò)dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value

>>> s.get('Michael' , 1) #key存在,返回對(duì)應(yīng)的value
95
>>> s.get('Michaels') //返回None的時(shí)候Python的交互式命令行不顯示結(jié)果。
>>> s.get('Michaels' , 1) #key不存在,返回自己指定的value
1

用pop(key)方法刪除一個(gè)key

>>> s.pop('Bob')  //對(duì)應(yīng)的value也會(huì)從dict中刪除:
75
>>> s
{'Michael': 95, 'Tracy': 85}

注意,dict內(nèi)部存放的順序和key放入的順序是沒(méi)有關(guān)系的。

重要:使用字典來(lái)統(tǒng)計(jì)list中相同元素出現(xiàn)的個(gè)數(shù)

li = ['apple','banana','orange','grape','orange','grape','orange','grape']
li_count = {}
for fruit in li:
    if fruit in li_count:
        li_count[fruit] = li_count[fruit] + 1
    else:
        li_count[fruit] = 1
print (li_count)
#{'apple': 1, 'banana': 1, 'orange': 3, 'grape': 3}

和list比較,dict有以下幾個(gè)特點(diǎn):
1.查找和插入的速度極快,不會(huì)隨著key的增加而變慢;
2.需要占用大量的內(nèi)存,內(nèi)存浪費(fèi)多。

而list相比dict:
1.查找和插入的時(shí)間隨著元素的增加而增加;
2.占用空間小,浪費(fèi)內(nèi)存很少。
所以,dict是用空間來(lái)?yè)Q取時(shí)間的一種方法。

dict的key必須是不可變對(duì)象
因?yàn)閐ict根據(jù)key來(lái)計(jì)算value的存儲(chǔ)位置(哈希算法),如果每次計(jì)算相同的key得出的結(jié)果不同,那dict內(nèi)部就完全混亂了。
要保證hash的正確性,作為key的對(duì)象就不能變。在Python中,字符串、整數(shù)等都是不可變的,因此,可以放心地作為key。而list是可變的,就不能作為key

>>> key = [1, 2, 3]
>>> d[key] = 'a list'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

5.4 序列

列表、元組和字符串都是序列,序列的主要特點(diǎn)是可以通過(guò)索引操作符讓我們可以直接從序列中抓取一個(gè)特定項(xiàng)目。
既然是序列,就具有切片操作,即取出序列的薄片,例如序列的一部分。

shoplist = ['apple', 'mango', 'carrot', 'banana']
name = 'swaroop'

#使用索引取出元素
print('Item 0 is', shoplist[0])  #Item 0 is apple
print('Item -1 is', shoplist[-1])  #Item -1 is banana
print('Item -2 is', shoplist[-2])  #Item -2 is carrot
print('Character 0 is', name[0]) #Character 0 is s

#對(duì)list切片
print('Item 1 to 3 is', shoplist[1:3])  #Item 1 to 3 is ['mango', 'carrot']
print('Item 2 to end is', shoplist[2:]) #Item 2 to end is ['carrot', 'banana']
print('Item 1 to -1 is', shoplist[1:-1]) #Item 1 to -1 is ['mango', 'carrot']
print('Item start to end is', shoplist[:]) #Item start to end is ['apple', 'mango', 'carrot', 'banana']

#對(duì)string切片
print('characters 1 to 3 is', name[1:3]) #characters 1 to 3 is wa

#給切片規(guī)定第三個(gè)參數(shù),就是切片的步長(zhǎng)(默認(rèn)步長(zhǎng)是1)
>>> shoplist = ['apple', 'mango', 'carrot', 'banana']
>>> shoplist[::2]
['apple', 'carrot']

5.5 集合set

集合是沒(méi)有順序的簡(jiǎn)單對(duì)象的聚集。當(dāng)在聚集中一個(gè)對(duì)象的存在比其順序或者出現(xiàn)的次數(shù)重要時(shí)使用集合。
使用集合,可以檢查是否是成員,是否是另一個(gè)集合的子集,得到兩個(gè)集合的交集等等。
set和dict類似,也是一組key的集合,但不存儲(chǔ)value。由于key不能重復(fù),所以,在set中,沒(méi)有重復(fù)的key。
要?jiǎng)?chuàng)建一個(gè)set,需要提供一個(gè)list作為輸入集合:

>>> s = set([1, 2, 3])
>>> s
{1, 2, 3} //顯示的順序也不表示set是有序的,set是無(wú)序和無(wú)重復(fù)元素的集合

>>> s = set([1, 1, 2, 2, 3, 3]) //list中可以有重復(fù)元素,但重復(fù)元素在set中自動(dòng)被過(guò)濾
>>> s
{1, 2, 3}

>>> s.add(4) //通過(guò)add(key)方法可以添加元素到set中
>>> s
{1, 2, 3, 4}
>>> s.add(4) //可以重復(fù)添加,但不會(huì)有效果:
>>> s
{1, 2, 3, 4}
>>> dd = s.copy()  #copy方法復(fù)制集合
>>> dd
{1, 2, 3, 4}
>>> dd.issuperset(s) #檢查一個(gè)集合是否是另一個(gè)集合的子集
True
>>> s.remove(4) //通過(guò)remove(key)方法可以刪除元素
>>> s
{1, 2, 3} 

兩個(gè)set可以做數(shù)學(xué)意義上的交集、并集等操作:

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

set和dict的區(qū)別
set和dict的唯一區(qū)別僅在于沒(méi)有存儲(chǔ)對(duì)應(yīng)的value,但是,set的原理和dict一樣,所以,同樣不可以放入可變對(duì)象,因?yàn)闊o(wú)法判斷兩個(gè)可變對(duì)象是否相等,也就無(wú)法保證set內(nèi)部“不會(huì)有重復(fù)元素”。

5.6再議不可變對(duì)象

例如str是不變對(duì)象,而list是可變對(duì)象。
對(duì)于不變對(duì)象來(lái)說(shuō),調(diào)用對(duì)象自身的任意方法,也不會(huì)改變?cè)搶?duì)象自身的內(nèi)容。相反,這些方法會(huì)創(chuàng)建新的對(duì)象并返回,這樣,就保證了不可變對(duì)象本身永遠(yuǎn)是不可變的。
對(duì)于可變對(duì)象,比如list,對(duì)list進(jìn)行操作,list內(nèi)部的內(nèi)容是會(huì)變化的,比如:

>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']

而對(duì)于不可變對(duì)象,比如str,對(duì)str進(jìn)行操作:

>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'

雖然字符串有個(gè)replace()方法,也確實(shí)變出了'Abc',但變量a最后仍是'abc',應(yīng)該怎么理解呢?
我們先把代碼改成下面這樣:

>>> a = 'abc' //注意a是變量,而'abc'才是字符串對(duì)象!
>>> b = a.replace('a', 'A') //replace方法創(chuàng)建了一個(gè)新字符串'Abc'并返回
>>> b //用變量b指向該新字符串變量,變量b僅僅引用那個(gè)對(duì)象,而不是表示這個(gè)對(duì)象本身
'Abc'
>>> a //變量a仍指向原有的字符串'abc'
'abc'

5.7 關(guān)于字符串的更多內(nèi)容

字符串也是對(duì)象,同樣具有方法。這些方法可以完成包括檢驗(yàn)一部分字符串和去除空格在內(nèi)的各種工作。
你在程序中使用的字符串都是str 類的對(duì)象。
如果要了解這些方法的完整列表,請(qǐng)參見help(str)。

>>> name = 'Swaroop'
>>> name.startswith('Swa')  #tartwith 方法是用來(lái)測(cè)試字符串是否以給定字符串開始
True
>>> 'a' in name  #in 操作符用來(lái)檢驗(yàn)一個(gè)給定字符串是否為另一個(gè)字符串的一部分
True
>>> name.find('war') != -1 #find 方法用來(lái)找出給定字符串在另一個(gè)字符串中的位置,或者返回-1 以表示找不到子字符串
True
>>> name.find('oop')
4
>>> '-'.join(['tan','yu']) #join方法連接字符串
'tan-yu'

6 函數(shù)

函數(shù)是重用的程序段。它們?cè)试S你給一個(gè)語(yǔ)句塊一個(gè)名稱,然后你用這個(gè)名字可以在你的程序的任何地方,任意多次地運(yùn)行這個(gè)語(yǔ)句塊。這被稱為調(diào)用函數(shù)。

6.1 內(nèi)建函數(shù)

Python內(nèi)置了很多有用的函數(shù),我們可以直接調(diào)用。要調(diào)用一個(gè)函數(shù),需要知道函數(shù)的名稱和參數(shù)。查看所有內(nèi)置函數(shù)

>>> abs(100) //abs函數(shù)獲取一個(gè)參數(shù)的返回值
100
>>> abs(-20)
20
>>> abs(12.34)
12.34

>>> max(2, 3, 1, -5) //max()函數(shù)可以接收任意多個(gè)參數(shù),返回最大的那個(gè)
3

數(shù)據(jù)類型轉(zhuǎn)換

>>> int('123') //int()函數(shù)可以把其他數(shù)據(jù)類型轉(zhuǎn)換為整數(shù)
123
>>> int(12.34)
12
>>> float('12.34')
12.34
>>> str(1.23)
'1.23'
>>> str(100)
'100'
>>> bool(1)
True
>>> bool('')
False

函數(shù)名其實(shí)就是指向一個(gè)函數(shù)對(duì)象的引用,完全可以把函數(shù)名賦給一個(gè)變量,相當(dāng)于給這個(gè)函數(shù)起了一個(gè)“別名”:

>>> a = abs # 變量a指向abs函數(shù)
>>> a(-1) # 所以也可以通過(guò)a調(diào)用abs函數(shù)
1

6.2 定義函數(shù)

在Python中,定義一個(gè)函數(shù)要使用def語(yǔ)句,依次寫出函數(shù)名、括號(hào)、括號(hào)中的參數(shù)和冒號(hào):,然后,在縮進(jìn)塊中編寫函數(shù)體,函數(shù)的返回值用return語(yǔ)句返回。

求絕對(duì)值函數(shù)my_abs

def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

在Python交互環(huán)境中定義函數(shù)時(shí),注意Python會(huì)出現(xiàn)...的提示。函數(shù)定義結(jié)束后需要按兩次回車重新回到>>>提示符下

6.3 函數(shù)的參數(shù)

函數(shù)中的參數(shù)名稱為形參,而你提供給函數(shù)調(diào)用的值稱為實(shí)參。
Python的函數(shù)定義非常簡(jiǎn)單,但靈活度卻非常大。除了正常定義的必選參數(shù)外,還可以使用默認(rèn)參數(shù)、可變參數(shù)和關(guān)鍵字參數(shù),使得函數(shù)定義出來(lái)的接口,不但能處理復(fù)雜的參數(shù),還可以簡(jiǎn)化調(diào)用者的代碼。

位置參數(shù)
def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

power(x, n)函數(shù)有兩個(gè)參數(shù):x和n,這兩個(gè)參數(shù)都是位置參數(shù),調(diào)用函數(shù)時(shí),傳入的兩個(gè)值按照位置順序依次賦給參數(shù)x和n。

默認(rèn)參數(shù)

對(duì)于上述代碼,由于我們經(jīng)常計(jì)算x2,所以完全可以把第二個(gè)參數(shù)n的默認(rèn)值設(shè)定為2

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

調(diào)用power(5)時(shí),相當(dāng)于調(diào)用power(5, 2):

>>> power(5)
25
>>> power(5, 2)
25

而對(duì)于n > 2的其他情況,就必須明確地傳入n,比如power(5, 3)。

默認(rèn)參數(shù)的好處
最大的好處是能降低調(diào)用函數(shù)的難度。而一旦需要更復(fù)雜的調(diào)用時(shí),又可以傳遞更多的參數(shù)來(lái)實(shí)現(xiàn)。無(wú)論是簡(jiǎn)單調(diào)用還是復(fù)雜調(diào)用,函數(shù)只需要定義一個(gè)。

把年齡和城市設(shè)為默認(rèn)參數(shù):

def enroll(name, gender, age=6, city='Beijing'):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)

這樣,大多數(shù)學(xué)生注冊(cè)時(shí)不需要提供年齡和城市,只提供必須的兩個(gè)參數(shù):

>>> enroll('Sarah', 'F')
name: Sarah
gender: F
age: 6
city: Beijing

只有與默認(rèn)參數(shù)不符的學(xué)生才需要提供額外的信息:

enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')

注意:默認(rèn)參數(shù)必須指向不變對(duì)象!

可變參數(shù)

可變參數(shù)就是傳入的參數(shù)個(gè)數(shù)是可變的,可以是1個(gè)、2個(gè)到任意個(gè),還可以是0個(gè)。

給定一組數(shù)字a,b,c……,計(jì)算a2 + b2 + c2 + …
由于參數(shù)個(gè)數(shù)不確定,我們首先想到可以把a(bǔ),b,c……作為一個(gè)list或tuple傳進(jìn)來(lái)

def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

但是調(diào)用的時(shí)候,需要先組裝出一個(gè)list或tuple:

>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84

如果利用可變參數(shù),把函數(shù)的參數(shù)改為可變參數(shù):

def calc(*numbers): //在函數(shù)內(nèi)部,參數(shù)numbers接收到的是一個(gè)tuple
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

利用可變參數(shù),調(diào)用函數(shù)的方式也可以簡(jiǎn)化:

>>> calc(1, 2, 3) 
14
>>> calc(1, 3, 5, 7)
84

如果已經(jīng)有一個(gè)list或者tuple,要調(diào)用一個(gè)可變參數(shù)怎么辦?
Python允許你在list或tuple前面加一個(gè)*號(hào),把list或tuple的元素變成可變參數(shù)傳進(jìn)去:

>>> nums = [1, 2, 3]
>>> calc(*nums) //*nums表示把nums這個(gè)list的所有元素作為可變參數(shù)傳進(jìn)去
14 

關(guān)鍵字參數(shù)

可變參數(shù)允許你傳入0個(gè)或任意個(gè)參數(shù),這些可變參數(shù)在函數(shù)調(diào)用時(shí)自動(dòng)組裝為一個(gè)tuple。而關(guān)鍵字參數(shù)允許你傳入0個(gè)或任意個(gè)含參數(shù)名的參數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動(dòng)組裝為一個(gè)dict。

def person(name, age, **kw): //函數(shù)person除了必選參數(shù)name和age外,還接受關(guān)鍵字參數(shù)kw
    print('name:', name, 'age:', age, 'other:', kw)

調(diào)用函數(shù)

>>> person('Michael', 30) //可以只傳入必選參數(shù)
name: Michael age: 30 other: {}

>>> person('Bob', 35, city='Beijing') //也可以傳入任意個(gè)數(shù)的關(guān)鍵字參數(shù)
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

和可變參數(shù)類似,也可以先組裝出一個(gè)dict,然后,把該dict轉(zhuǎn)換為關(guān)鍵字參數(shù)傳進(jìn)去:

>>> extra = {'city': 'Beijing', 'job': 'Engineer'} 
>>> person('Jack', 24, **extra)//**extra表示把extra這個(gè)dict的所有key-value用關(guān)鍵字參數(shù)傳入到函數(shù)的**kw參數(shù)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
命名關(guān)鍵字參數(shù)(限制關(guān)鍵字參數(shù)的名字)

對(duì)于關(guān)鍵字參數(shù),函數(shù)的調(diào)用者可以傳入任意不受限制的關(guān)鍵字參數(shù)。至于到底傳入了哪些,就需要在函數(shù)內(nèi)部通過(guò)kw檢查。
以person()函數(shù)為例,我們希望檢查是否有city和job參數(shù):

def person(name, age, **kw):
    if 'city' in kw:
        # 有city參數(shù)
        pass
    if 'job' in kw:
        # 有job參數(shù)
        print('job_parameter')
    print('name:', name, 'age:', age, 'other:', kw)
    
person('Michael', 30, lucy=20, ass=100, job='teacher') 
輸出:
job_parameter
name: Michael age: 30 other: {'lucy': 20, 'ass': 100, 'job': 'teacher'}

如果要限制關(guān)鍵字參數(shù)的名字,就可以用命名關(guān)鍵字參數(shù),例如,只接收city和job作為關(guān)鍵字參數(shù)。這種方式定義的函數(shù)如下:

def person(name, age, *, city, job): //需要一個(gè)特殊分隔符*,*后面的參數(shù)被視為命名關(guān)鍵字參數(shù)。
//注意:如果缺少*,Python解釋器將無(wú)法識(shí)別位置參數(shù)和命名關(guān)鍵字參數(shù):
    print(name, age, city, job)

調(diào)用方式如下:

>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer

如果函數(shù)定義中已經(jīng)有了一個(gè)可變參數(shù),后面跟著的命名關(guān)鍵字參數(shù)就不再需要一個(gè)特殊分隔符*了

def person(name, age, *args, city, job):
    print(name, age, args, city, job)

調(diào)用方式如下

>>> person('Jack', 24,'wwww', city='Beijing', job='Engineer') //命名關(guān)鍵字參數(shù)必須傳入?yún)?shù)名,這和位置參數(shù)不同
Jack 24 ('wwww',) Beijing Engineer

命名關(guān)鍵字參數(shù)可以有缺省值,從而簡(jiǎn)化調(diào)用:

def person(name, age, *, city='Beijing', job):
    print(name, age, city, job)

由于命名關(guān)鍵字參數(shù)city具有默認(rèn)值,調(diào)用時(shí),可不傳入city參數(shù)

>>> person('Jack', 24, job='Engineer')
Jack 24 Beijing Engineer
參數(shù)組合

在采用不同參數(shù)的情況下,不同參數(shù)定義的順序必須是:必選參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、命名關(guān)鍵字參數(shù)、關(guān)鍵字參數(shù)。
比如定義一個(gè)函數(shù),包含上述若干種參數(shù):

def f1(a, b, c=0, *args, **kw):  //必選參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw)://必選參數(shù)、默認(rèn)參數(shù)、命名關(guān)鍵字參數(shù)、關(guān)鍵字參數(shù)
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

在函數(shù)調(diào)用的時(shí)候,Python解釋器自動(dòng)按照參數(shù)位置和參數(shù)名把對(duì)應(yīng)的參數(shù)傳進(jìn)去。
通過(guò)一個(gè)tuple和dict,你也可以調(diào)用上述函數(shù):

>>> args = (1, 2, 3, 4)
>>> kw = {'d': 99, 'x': '#'}
>>> f1(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}

所以,對(duì)于任意函數(shù),都可以通過(guò)類似func(*args, **kw)的形式調(diào)用它,無(wú)論它的參數(shù)是如何定義的。

python參數(shù)小結(jié)
  • 默認(rèn)參數(shù)一定要用不可變對(duì)象,如果是可變對(duì)象,程序運(yùn)行時(shí)會(huì)有邏輯錯(cuò)誤!
  • 要注意定義可變參數(shù)和關(guān)鍵字參數(shù)的語(yǔ)法:
    • *args是可變參數(shù),args接收的是一個(gè)tuple;
    • **kw是關(guān)鍵字參數(shù),kw接收的是一個(gè)dict。
  • 以及注意調(diào)用函數(shù)時(shí)如何傳入可變參數(shù)和關(guān)鍵字參數(shù)的語(yǔ)法:
    • 可變參數(shù)既可以直接傳入:func(1, 2, 3),又可以先組裝list或tuple,再通過(guò)*args傳入:func(*(1, 2, 3));
    • 關(guān)鍵字參數(shù)既可以直接傳入:func(a=1, b=2),又可以先組裝dict,再通過(guò)**kw傳入:func(**{'a': 1, 'b': 2})。
  • 使用*args**kw是Python的習(xí)慣寫法,當(dāng)然也可以用其他參數(shù)名,但最好使用習(xí)慣用法。
  • 命名的關(guān)鍵字參數(shù)是為了限制調(diào)用者可以傳入的參數(shù)名,同時(shí)可以提供默認(rèn)值。
  • 定義命名的關(guān)鍵字參數(shù)在沒(méi)有可變參數(shù)的情況下不要忘了寫分隔符*,否則定義的將是位置參數(shù)。

6.4 return 語(yǔ)句

return 語(yǔ)句用來(lái)從一個(gè)函數(shù)返回即跳出函數(shù)。我們也可選是否從函數(shù)返回一個(gè)
值。

#!/usr/bin/python
def max1(a,b):
    if a > b:
        return a
    else:
        return b
print(max1(5,3))
輸出:5

注意,沒(méi)有返回值的 return 語(yǔ)句等價(jià)于 return None 。 None 是 Python 中表示沒(méi)有任何東西的特殊類型。例如,如果一個(gè)變量的值為 None ,可以表示它沒(méi)有值。除非你提供你自己的 return 語(yǔ)句,每個(gè)函數(shù)都在結(jié)尾暗含有 return None 語(yǔ)句。例如:

def someFunction(): 
    pass  #pass 語(yǔ)句在 Python 中表示一個(gè)空的語(yǔ)句塊。

7 文件處理

7.1讀取文件

f = open('test.txt', 'r') #使用Python內(nèi)置的open()函數(shù),傳入文件名和標(biāo)示符,標(biāo)示符'r'表示讀
g = f.read()  #調(diào)用read()方法可以一次讀取文件的全部?jī)?nèi)容
print(g) #read me
f.close() #調(diào)用close()方法關(guān)閉文件。文件使用完畢后必須關(guān)閉,因?yàn)槲募?duì)象會(huì)占用操作系統(tǒng)的資源

如果文件不存在,open()函數(shù)就會(huì)拋出一個(gè)IOError的錯(cuò)誤,一旦出錯(cuò),后面的f.close()就不會(huì)調(diào)用。為了保證無(wú)論是否出錯(cuò)都能正確地關(guān)閉文件,with語(yǔ)句來(lái)自動(dòng)幫我們調(diào)用close()方法,代碼更佳簡(jiǎn)潔,并且不必自己再調(diào)用f.close()方法。

with open('test.txt', 'r') as f:
    print(f.read()) 

調(diào)用read()會(huì)一次性讀取文件的全部?jī)?nèi)容,如果文件有10G,內(nèi)存就爆了,所以,要保險(xiǎn)起見,可以反復(fù)調(diào)用read(size)方法,每次最多讀取size個(gè)字節(jié)的內(nèi)容。另外,調(diào)用readline()可以每次讀取一行內(nèi)容,調(diào)用readlines()一次讀取所有內(nèi)容并按行返回list。

for line in f.readlines():
    print(line.strip()) # 把末尾的'\n'刪掉

strip() 方法用于移除字符串頭尾指定的字符(默認(rèn)為空格)

str = "0000000this is string example....wow!!!0000000";
print str.strip( '0' ); #this is string example....wow!!!

7.2寫入文件

寫文件和讀文件是一樣的,唯一區(qū)別是調(diào)用open()函數(shù)時(shí),傳入標(biāo)識(shí)符'w'或者'wb'表示寫文本文件或?qū)懚M(jìn)制文件:

f = open('test2.txt', 'w')
f.write('Hello, world!')
f.write('\n')
f.write('123456')
f.close() #可以反復(fù)調(diào)用write()來(lái)寫入文件,但是務(wù)必要調(diào)用f.close()來(lái)關(guān)閉文件

#Hello, world!
#123456

忘記調(diào)用close()的后果是數(shù)據(jù)可能只寫了一部分到磁盤,剩下的丟失了。所以,還是用with語(yǔ)句來(lái)得保險(xiǎn):

with open('test2.txt', 'w') as f:
    f.write('Hello, world!')

模式可以為讀模式(’r’)、寫模式(’w’)或追加模式(’a’)。事實(shí)上還有多得多的模式可以使用,你可以使用 help(file) 來(lái)了解它們的詳情。

若想要寫入文件的內(nèi)容是追加在原文件內(nèi)容之后,而不是覆蓋,應(yīng)該使用追加模式(’a’)。

with open('test2.txt', 'a') as f:
    f.write('Hello, world!')

split()方法
split()通過(guò)指定分隔符對(duì)字符串進(jìn)行切片,如果參數(shù)num 有指定值,則僅分隔 num 個(gè)子字符串。

str.split(str="", num=string.count(str))
str -- 分隔符,默認(rèn)為所有的空字符,包括空格、換行(\n)、制表符(\t)等。
num -- 分割次數(shù)。
str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );
print str.split(' ', 1 );

#輸出結(jié)果如下:
['Line1-abcdef', 'Line2-abc', 'Line4-abcd']
['Line1-abcdef', '\nLine2-abc \nLine4-abcd']

讀取csv文件

weather_data = []
f = open('weather.csv', 'r')
data = f.read()
rows = data.split('\n')
for row in rows:
    split_row = row.split(',')
    weather_data.append(split_row)
print(weather_data)
#輸出結(jié)果
[['1', 'sunny'], ['2', 'sunny'], ['3', 'sunny'], ['4', 'sunny'], ['5', 'rain'], ['6', 'fog'], ['7', 'rain'], ['8', 'fog'], ['9', 'rain'], ['10', 'sunny']]

當(dāng)只想要取出第二列的weather

weather_data = []
f = open('weather.csv', 'r')
data = f.read()
rows = data.split('\n')
for row in rows:
    split_row = row.split(',')
    weather_data.append(split_row)
    weather = []
    for row in weather_data:
        weather.append(row[1])
print(weather)
f.close()
#輸出結(jié)果
['sunny', 'sunny', 'sunny', 'sunny', 'rain', 'fog', 'rain', 'fog', 'rain', 'sunny']
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Python 基礎(chǔ)教程 實(shí)例(Python 2.0+) 實(shí)例(Python 3.0+) Python 簡(jiǎn)介 Pyt...
    縱我不往矣閱讀 64,863評(píng)論 0 23
  • 一、python 變量和數(shù)據(jù)類型 1.整數(shù) Python可以處理任意大小的整數(shù),當(dāng)然包括負(fù)整數(shù),在Python程序...
    績(jī)重KF閱讀 2,013評(píng)論 0 1
  • 最近在慕課網(wǎng)學(xué)習(xí)廖雪峰老師的Python進(jìn)階課程,做筆記總結(jié)一下重點(diǎn)。 基本變量及其類型 變量 在Python中,...
    victorsungo閱讀 1,939評(píng)論 0 5
  • 簡(jiǎn)介 Python是開源的Python由很多解釋器:CPython(官方),IPython(增強(qiáng)交互模式),PyP...
    齊天大圣李圣杰閱讀 383評(píng)論 0 3
  • 1.輸出 print 打印print語(yǔ)句也可以跟上多個(gè)字符串,用逗號(hào)“,”隔開,print會(huì)依次打印每個(gè)字符串,遇...
    積微微微閱讀 417評(píng)論 0 0

友情鏈接更多精彩內(nèi)容