作者:賈勝杰,碩士,退役軍人,電氣工程專業(yè),現(xiàn)成功轉(zhuǎn)行K12領(lǐng)域數(shù)據(jù)挖掘工程師,不僅在數(shù)據(jù)清理、分析和預(yù)測方向,而且在自制力和高效學(xué)習(xí)方面都有豐富經(jīng)驗(yàn)。
Python可以說是近兩年最火的編程語言了,這主要是因?yàn)樗囊韵聝蓚€(gè)突出特點(diǎn):
??文中會(huì)涉及的編程相關(guān)術(shù)語較多,關(guān)鍵術(shù)語我會(huì)進(jìn)行解釋,其他的我會(huì)以鏈接的形式供大家自行查閱。
本篇文章包含的知識(shí)點(diǎn)有:環(huán)境搭建,Python編碼規(guī)范,變量與字面量,數(shù)據(jù)類型與運(yùn)算符,控制流,函數(shù)。
環(huán)境搭建
所謂“環(huán)境搭建”,就是在電腦本機(jī)或線上提前準(zhǔn)備好Python數(shù)據(jù)分析的基本需求,好比是在烹飪前先搭建好灶臺(tái)一樣。這里相對簡單,我做出一些推薦和評價(jià),大家按需去選擇安裝就行。
本地搭建首選:Anaconda[https://www./], the world's most popular data science platform.
對小白友好,直接下載安裝即可,內(nèi)置數(shù)據(jù)科學(xué)相關(guān)的所有庫;后期熟練了之后,還可以用于環(huán)境&庫管理;自帶Jupyter Notebook[https:///](可能是現(xiàn)階段最好用的數(shù)據(jù)科學(xué)工具)和Spyder[https://www.](不是特別好用的Python IDE[https://en./wiki/Integrated_development_environment])。
線上首選:Azure Notebook[https://notebooks./]。如果你不想在自己的電腦上配置環(huán)境,那么你可以嘗試下線上的Notebook;如果你用Google方便,那強(qiáng)烈推薦 Google Colab[https://colab.research.google.com/],在這里你還能用上免費(fèi)的GPU。
編輯器推薦:Visual Studio Code[https://code./],拓展豐富,配色美觀,一旦用上就會(huì)愛上。
配置好之后嘗試你的第一個(gè)python代碼吧!
print('Hello world!')
Python編碼規(guī)范
編碼規(guī)范是法律
一樣的存在,非常重要,所以請大家一定要恪守這個(gè)法律,在初學(xué)階段打好基礎(chǔ),養(yǎng)成良好的編碼習(xí)慣。
行與縮進(jìn)
python最具特色的就是使用縮進(jìn)來表示代碼塊, 同一個(gè)代碼塊的語句必須包含相同的縮進(jìn)空格數(shù),縮進(jìn)的空格數(shù)是可變的,但是有個(gè)不成文的規(guī)定就是使用4個(gè)空格的縮進(jìn)。
比如:
if True:
print ('True')
else:
print ('False')
但如果像如下這樣就會(huì)因?yàn)榭s進(jìn)問題報(bào)錯(cuò):
if True:
print ('Answer')
print ('True')
else:
print ('Answer')
print ('False') # 縮進(jìn)不一致,會(huì)導(dǎo)致運(yùn)行錯(cuò)誤
報(bào)錯(cuò)會(huì)提示如下:
IndentationError: unindent does not match any outer indentation level
所以,如果你的程序運(yùn)行后,出現(xiàn)這種錯(cuò)誤提示,那你就要檢查下,你的代碼縮進(jìn)是不是有問題了。
注釋
Python中單行注釋以 # 開頭,多行注釋可以用多個(gè) #
號(hào),或者 '''
和 '''
(主要作聲明函數(shù)用),示例如下:
# 注釋1
# 注釋2
def hello():
'''
this is a print function.
'''
print ('Hello,Python!')
變量與字面量
變量與數(shù)學(xué)方程中的概念類似,都是用于指代某一值,便于在其他位置調(diào)用。在Python中,我們按照變量名 = 某值
的方式對變量進(jìn)行賦值
:
a = 123
name = 'Allen'
字面量就是那些只能代表自己實(shí)際值的量,比如說上面代碼中的123
和'Allen'
,字面量不能做為變量名。
??變量名的命名規(guī)則:用字母或字母數(shù)字的組合表示;數(shù)字不能作為變量名的開頭;變量名中不能出現(xiàn)空格,可以用_
代替空格;變量名要起得有意義,比如說表示名字,最好使用name
或name_1
等。
數(shù)據(jù)類型
我們在工作中會(huì)遇到各種類型的數(shù)據(jù),比如數(shù)字、字符、圖片等等,那么Python在處理這些數(shù)據(jù)時(shí),會(huì)根據(jù)他們的類型,貼上一個(gè)標(biāo)簽,這個(gè)標(biāo)簽就是數(shù)據(jù)類型
。
整型(int)
浮點(diǎn)型(float)
布爾型(bool)
??這里可能會(huì)有一些疑惑,在python中,所有的0
以及空值的布爾值都為False
, 比如說None,0(整型0),0.0(浮點(diǎn)型0),0.0+0.0j(復(fù)數(shù)0),''(空字符串),[](空列表),()(空元組),{}(空字典)等。這在后面做邏輯判斷中,非常有用。
字符串(str)
字符串就是由字符穿起來的串兒,會(huì)放在單引號(hào)或者雙引號(hào),甚至是三引號(hào)中。
??四引號(hào)可以嗎?自己試試看!
一般的,我們把一串字符放到引號(hào)中就可以定義一個(gè)字符串,但如果這串字符中就包含有引號(hào)時(shí),就會(huì)跟界定字符串的引號(hào)發(fā)生沖突,這怎么辦呢?比如說I'm Allen
或者He said:'Life is short.'
.其實(shí)并不難,我們只需要解決這個(gè)沖突就可以了
#方法一:換其他引號(hào)作為字符串的界定
str_a = “I'm Allen”
str_a = 'He said:'Life is short.''
#方法二:使用轉(zhuǎn)義符號(hào)
str_a = 'I'm Allen'
??特別的,三引號(hào)可以保持原字符串的排版格式,試試看~
當(dāng)我們想從某個(gè)字符串中提取某一個(gè)字符的時(shí)候,就需要用到索引
了,你可以把索引理解為某字符在字符串中的次序,然后把這個(gè)次序放到一對中括號(hào)里就可以了。比如
str_a = 'Life is short.' #定義一個(gè)字符串
#提取f,利用正索引(從左往右,從0開始計(jì)數(shù))
str_a[2]
#提取h,利用負(fù)索引(從右往左,從-1開始計(jì)數(shù))
str_a[-5]
索引是一個(gè)非常重要的概念,隨著學(xué)習(xí)的深入,你會(huì)發(fā)現(xiàn)索引無處不在。
利用索引提取字符串中某一部分就是切片。其用法為[起始位:終止位:步長]
,得到的是一個(gè)由起始位
到終止位
間隔為步長-1
的前閉后開區(qū)間。
str_a[3:6] #步長為1時(shí)可以省略,提取的結(jié)果為'e i'(注意空格也算一位)
str_a[1:6:2] #結(jié)果為'iei'
??str_a[::-1]
的結(jié)果會(huì)是什么呢?動(dòng)手試試看!
#查看字符串長度
len(str_a)
#修改字符串的大小寫
str_a.upper() #全部改為大寫
str_a.lower() #全部改為小寫
str_a.title() #改為首字母大寫
#查看字符's'在str_a中的索引
str_a.index('s')
#字符串拼接
str_a + str_b
str_a * n #str_a重復(fù)n次
列表(List)
寫在方括號(hào) [] 內(nèi),各元素用逗號(hào)分隔開。元素可以是數(shù)字、字符串或者列表??梢钥吹?,字符串是字符組成的可迭代對象(iterable),而列表是由元素組成的可迭代對象,所以,兩者的很多屬性都是相通的,比如說索引
和切片
都可以用在列表中。
str_a = '小學(xué)_數(shù)學(xué)_第一次考試'
#將str_a中的各個(gè)屬性挑出來
str_a.split('_') #根據(jù)字符'_'對字符串進(jìn)行分割
>>> 結(jié)果:['小學(xué)','數(shù)學(xué)','第一次考試']
#我們將列表list_a = ['小學(xué)','數(shù)學(xué)','第一次考試']合并為字符串
'_'.join(list_a) #將字符'_'添加到各個(gè)元素中間,并進(jìn)行連接
>>> 結(jié)果:'小學(xué)_數(shù)學(xué)_第一次考試'
len()
、index()
函數(shù)及+
/*
的用法與字符串一致。
#添加元素
list_a.append('a') #將字符a添加到list_a的末尾
list_a.insert(index,'a') #將字符a插入到list_a中索引為index的位置
#刪除元素
list_a.remove('a)
#排序
list_a.sort(reverse=False) #默認(rèn)升序,可設(shè)置reverse=True來實(shí)現(xiàn)降序
字典(Dictionary)
寫在大括號(hào){ }里,是一個(gè)無序的鍵(key):值(value)
對集合,每一對用逗號(hào)隔開。
key必須為不可變類型,如Number(數(shù)字)或String(字符串),并且在一個(gè)字典中每個(gè)key都是唯一的
#定義
dict_a = {'小明':'優(yōu)秀','小華':'優(yōu)秀','小李':'良好'}
#增加
dict_a['小王'] = '良好'
#提取
dict_a['小明']
dict_a.get('小明')
>>> 結(jié)果:'優(yōu)秀'
#查看所有key,value等
dict_a.keys()
dict_a.values()
dict_a.items() #返回所有的key,value對
#更新
dict_a.update(dict_b) #用dict_b更新dict_a
運(yùn)算符
算術(shù)運(yùn)算符
假設(shè) a = 12, b = 26
運(yùn)算符 | 描述 | 實(shí)例 |
---|
+ | 加,數(shù)字就是做加法/字符串就是拼接 | a + b 輸出結(jié)果 28 |
- | 減,做減法 | a - b 輸出結(jié)果 -28 |
* | 乘 ,數(shù)字的話就是相乘/字符串的話就是重復(fù)若干次 | a * b 輸出結(jié)果 312 |
/ | 除,做除法 | b / a 輸出結(jié)果 2.1666666666666665 (自動(dòng)轉(zhuǎn)化為浮點(diǎn)型) |
% | 取模 , 即做除法后的余數(shù) | b % a 輸出結(jié)果 2 |
** | 冪 | a**b 為12的26次方 |
// | 取整,即做除法后的商 | 9//2 輸出結(jié)果 4 , 9.0//2.0 輸出結(jié)果 4.0 |
賦值運(yùn)算符
運(yùn)算符 | 描述 | 實(shí)例 |
---|
= | 簡單的賦值運(yùn)算符 | c = a + b 將 a + b 的運(yùn)算結(jié)果賦值為 c |
+= | 加法賦值運(yùn)算符 | c += a 即 c = c + a(常用 i += 1,表示遞增) |
-= | 減法賦值運(yùn)算符 | c -= a 即 c = c - a |
比較運(yùn)算符
運(yùn)算符 | 描述 |
---|
== | 等于;比較對象是否相等 |
!= | 不等于;比較兩個(gè)對象是否不相等 |
> | 大于 ;返回x是否大于y |
< | 小于 ;返回x是否小于y。所有比較運(yùn)算符返回1表示真,返回0表示假。這分別與特殊的變量True和False等價(jià)。注意,這些變量名的大寫。 |
>= | 大于等于;返回x是否大于等于y。 |
<= | 小于等于;返回x是否小于等于y。 |
邏輯運(yùn)算符
運(yùn)算符 | 邏輯表達(dá)式 | 描述 |
---|
and | x and y | 即邏輯 “與” |
or | x or y | 即邏輯 “或” |
not | not x | 即邏輯 “非” |
成員運(yùn)算符
即查看指定的序列中是否存在某值,這個(gè)序列可以是字符串、列表或者元組。
運(yùn)算符 | 描述 |
---|
in | 找到值返回 True,否則返回 False。 |
not in | 與in相反 |
恒等運(yùn)算符
運(yùn)算符 | 描述 |
---|
is | 檢查兩邊是否恒等 |
is not | 檢查兩邊是否不恒等 |
控制流
條件語句if
循環(huán)語句
for循環(huán)
while循環(huán)
for循環(huán)和while循環(huán),兩者的相同點(diǎn)在于都能循環(huán)做一件重復(fù)的事情;不同點(diǎn)在于,for循環(huán)是在序列窮盡時(shí)停止,while循環(huán)是在條件不成立時(shí)停止。當(dāng)這個(gè)條件永遠(yuǎn)不為False時(shí),就會(huì)出現(xiàn)死循環(huán)。
其一般格式為:
while <判斷條件>:
<執(zhí)行語句>
break和continue
break 語句可以跳出 for 和 while 的循環(huán)體。
示例:
for letter in 'Python': # for實(shí)例
if letter == 't':
break
print ('當(dāng)前字母為 :', letter)
i = 10 # while實(shí)例
while i > 0:
print ('當(dāng)期變量值為 :', i)
i -= 1
if i == 5:
break
執(zhí)行語句后的輸出結(jié)果為:
當(dāng)前字母為 : P
當(dāng)前字母為 : y
當(dāng)期變量值為 : 10
當(dāng)期變量值為 : 9
當(dāng)期變量值為 : 8
當(dāng)期變量值為 : 7
當(dāng)期變量值為 : 6
continue是跳過當(dāng)前循環(huán)塊中的剩余語句, 也就是跳過continue后面的語句
示例:
for letter in 'Python': # for實(shí)例
if letter == 't':
continue
print ('當(dāng)前字母為 :', letter)
i = 5 # while實(shí)例
while i > 0:
i -= 1
if i == 3:
continue
print ('當(dāng)期變量值為 :', i)
執(zhí)行代碼后的輸出結(jié)果為:
當(dāng)前字母為 : P
當(dāng)前字母為 : y
當(dāng)前字母為 : h
當(dāng)前字母為 : o
當(dāng)前字母為 : n
當(dāng)期變量值為 : 4
當(dāng)期變量值為 : 2
當(dāng)期變量值為 : 1
當(dāng)期變量值為 : 0
綜上呢,for更適合可迭代情況下使用,while更適合不知道要循環(huán)多少次的時(shí)候使用。
zip函數(shù)
zip([a],[b])
使用zip函數(shù)可以節(jié)約不少內(nèi)存
可以使用list()來轉(zhuǎn)換輸出zip函數(shù)的結(jié)果
若zip的兩個(gè)輸入序列長度不一致,則以短的那個(gè)為參考
*zip可以理解為zip的反函數(shù),可以將元組解壓為列表
示例:
a = [1,2]
b = [3,4]
c = [5,6,7]
zip_1 = zip(a,b)
print(list(zip_1))
>>> [(1,3),(2,4)]
zip_2 = zip(a,c)
print(list(zip_2))
>>> [(1,5),(2,6)]
a1,c1 = zip(*zip_1)
print(a1,c1)
>>> (1,2) (3,4)
enumerate函數(shù)
該函數(shù)是將一個(gè)可遍歷的數(shù)據(jù)對象(如列表、元組或字符串)組合為一個(gè)帶索引和元素的元組
其一般格式為:
enumerate(<序列>, start=0)
#start表示下標(biāo)的起始位置
常與for…in…聯(lián)用
示例:
a = [1,2]
print('起始下標(biāo)為默認(rèn):')
for i,j in enumerate(a):
print(i,j)
print('起始下標(biāo)為1:')
for i,j in enumerate(a,start = 1):
print(i,j)
執(zhí)行代碼,輸出結(jié)果為:
起始下標(biāo)為默認(rèn):
0 1
1 2
起始下標(biāo)為1:
1 1
2 2
列表推導(dǎo)式
列表推導(dǎo)式是一種非常Pythonic的方式,可以簡單理解為:定義一個(gè)空表,然后用表中的語句填充該表。
其一般格式為:
[表達(dá)式 for 變量 in 序列或迭代對象]
示例:
#查看兩個(gè)列表中的不同元素
#普通方式
diff = []
for item in list_a:
if item not in list_b:
diff.append(item)
#列表推導(dǎo)式
[item for item in list_a if item not in list_b]
#與zip函數(shù)結(jié)合,計(jì)算兩個(gè)列表對應(yīng)元素之和
[i[0]+i[1] for i in zip(list_a,list_b)]
函數(shù)
定義函數(shù)
參數(shù)
默認(rèn)參數(shù)和關(guān)鍵字參數(shù)不在贅述,在此只講述一種不定長參數(shù)。
示例:
#定義函數(shù)
def tupleprint(a, *tupleb ):
'''
打印任何傳入的參數(shù)
'''
print ('輸出: ')
print (a)
print (tupleb)
#調(diào)用函數(shù)
tupleprint(1,2,3)
執(zhí)行代碼,輸出結(jié)果為:
輸出:
1
(2, 3)
變量作用域
變量的作用域就是能訪問該變量的程序部分。
在python中,只有模塊(module),類(class)以及函數(shù)(def、lambda)才會(huì)引入新的作用域 ,而其他如if/for/while等是不會(huì)引入新的作用域的。
全局變量即可以在整個(gè)程序范圍內(nèi)都可以訪問;局部變量只能在其被定義的函數(shù)內(nèi)調(diào)用。
示例:
global_a = 0 # 這是一個(gè)全局變量
# 定義函數(shù)
def sum( a, b ):
global_a = a + b # global_a在這里是局部變量.
print ('局部變量為: ', global_a)
return global_a
#調(diào)用函數(shù)
sum(1,2)
print ('全局變量為: ', global_a)
執(zhí)行代碼,輸出結(jié)果為:
局部變量為: 3
全局變量為: 0
當(dāng)局部代碼想要修改全局變量時(shí),就會(huì)用到global和nonlocal關(guān)鍵字了 。
示例:
num = 1
def fun1():
global num # 需要使用 global 關(guān)鍵字聲明
print(num)
num = 123
print(num)
fun1()
print(num)
執(zhí)行代碼,輸出結(jié)果為:
1
123
123
nonlocal的用法類似,用在嵌套函數(shù)中,當(dāng)只想修改嵌套作用域的變量而非全局變量時(shí)使用。
可更改對象與不可更改對象
在數(shù)據(jù)類型中也提到過,python中的可變類型(列表、字典和集合)與不可變類型(數(shù)字,字符串和元組),那在函數(shù)中作為變量進(jìn)行傳遞時(shí)會(huì)是怎樣呢?
示例1:
#定義函數(shù)
def fun1(a):
a = 2
print(a)
b = 1
fun1(b)
print(b)
示例2:
def fun2(list_a):
list_a.append(2)
print(list_a)
list_b = [0,1]
fun2(list_b)
print(list_b)
嘗試下,上面這兩個(gè)示例的輸出結(jié)果,有什么區(qū)別?
匿名函數(shù)
lambda函數(shù)在后續(xù)的Pandas數(shù)據(jù)分析中會(huì)經(jīng)常用到,一定要熟練掌握呀。
最后
對于小白來說,編寫代碼是個(gè)很大的挑戰(zhàn),如果剛開始寫不出來,那可以嘗試先按照‘目的-拆分步驟-逐個(gè)實(shí)現(xiàn)’的流程去寫偽代碼
,然后再翻譯成python語句,比如:
#問題:對學(xué)生進(jìn)行成績分級,90分以上為A,80分-90分為B,其余為C
#目的:輸入 成績,按照規(guī)則對應(yīng)為評分并輸出
#步驟&偽代碼:
#1.輸入成績
#2.對成績進(jìn)行判斷,如果成績大于90,則返回A;如果成績大于80則返回B;其余返回C;(分情況判定 用if語句)
#翻譯成python
def score_to_grade(score): #定義函數(shù),輸入成績score
if score > 90:
return ('你獲得了:A')
elif score > 80:
return ('你獲得了:B')
else:
return ('你獲得了:C')
這里只是舉了一個(gè)很簡單的例子,但面對的問題越復(fù)雜,就越要嘗試用目的-拆分步驟-逐個(gè)實(shí)現(xiàn)
的流程去做,復(fù)雜問題就會(huì)迎刃而解了。
此外,有問題可以通過以下途徑解決:
必應(yīng)搜索
菜鳥教程(http://www.runoob.com/python3/python3-tutorial.html)
stackoverflow(https:///)
Python for Data Analysis, 2nd Edition(http://ick/Qve)
Python Cookbook(http://python3-cookbook./zh_CN/latest/)