目錄
最重要的工具PIP, 以及常用的網站,IDE推薦
基本概念
函數
進階概念:裝飾器,迭代器,列表推導式,匿名函數
面向對象
標準庫以及常用的庫
最重要的工具PIP, 以及常用的網站,IDE推薦
Python 能干什么
開發一些簡單的腳本,自動化完成一些繁復的工作
web (相關的框架 flask, django)
數據分析(相關的庫: Numpy)
爬蟲
以及偶爾裝個逼—> 川普撞臉希拉里(基于 OpenCV 的面部特征交換)
Python3 的安裝
如果你正在使用Mac,系統是OS X 10.8~10.10,那么系統自帶的Python版本是2.7。要安裝最新的Python 3.5,有兩個方法:
方法一:從Python官網下載Python 3.5的安裝程序(網速慢的同學請移步國內鏡像),雙擊運行并安裝;
方法二:如果安裝了Homebrew,直接通過命令brew install python3
安裝即可。
Homebrew安裝及使用
Homebrew 官網
Ruby 安裝
pip is already installed if you're using Python 2 >=2.7.9 or Python 3 >=3.4 binaries downloaded from python.org, but you'll need to upgrade pip.
? 對于國內用戶,因為有墻的存在,用pip 安裝第三方包的時候,下載速率很慢。我們需要配置pip的config 文件,假如國內的鏡像網站。
配置pip 鏡像文件
[global]
timeout = 6000
index-url = http://pypi.douban.com/simple/
[install]
use-mirrors = true
mirrors = http://pypi.douban.com/simple/
trusted-host = pypi.douban.com
IDE: PyCharm
Pycharm official website
Pycharm 使用教程
基本概念
數據類型
n = 123
f = 456.789
s1 = 'Hello, world'
s2 = 'Hello, 'Adam''
s3 = r'Hello, "Bart"'
s4 = r'''Hello,
... Lisa!'''
print(s1)
Hello, world
print(s2)
Hello, 'Adam'
print(s3)
Hello, "Bart"
print(s4)
Hello,
Lisa!
print()
len()
b'AbC'.decode()
'AbC'
'ANC'.encode('utf-8')
b'ANC'A = 'Allen'
'Hello %s' % A
'Hello Allen''%2d-%02d' % (3, 1)
' 3-01'
'%.2f' % 3.1415926
'3.14'
List 與 tuple
list 就是 NSMutableArray, tuple就是 NSArray
classmatess_L = ['Michael', 'Bob', 'Tracy']
classmates = ('Michael', 'Bob', 'Tracy')
?
classmates_L.append('Allen')
print(classmates_L)
['Michael', 'Bob', 'Tracy', 'Allen']
classmates.append('Allen')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
?
List:
append()
classmates_L.pop()
'Allen'
print(classmates_L)
['Michael', 'Bob', 'Tracy']
classmates_L.pop(2)
'Tracy'
print(classmates_L)
['Michael', 'Bob']len(classmates_L)
2
classmates_L[-1]
'Allen'
classmates_L.insert(1,'Allen')
print(classmates_L)
['Michael', 'Allen', 'Bob']
避免歧義,定義一個元素的tuple,在元素后面要加上,
?
name= ('Allen',)
print(name)
('Allen',)
print(s3)
Hello, "Bart"
>>> print(s4)
Hello,
Lisa!
>>>
字符串與編碼
print()
len()
>>> b'AbC'.decode()
'AbC'
>>> 'ANC'.encode('utf-8')
b'ANC'
>>>
>>> A = 'Allen'
>>> 'Hello %s' % A
'Hello Allen'
>>>
>>> '%2d-%02d' % (3, 1)
' 3-01'
>>> '%.2f' % 3.1415926
'3.14'
List 與 tuple
list 就是 NSMutableArray, tuple就是 NSArray
classmatess_L = ['Michael', 'Bob', 'Tracy']
classmates = ('Michael', 'Bob', 'Tracy')
?
>>> classmates_L.append('Allen')
>>> print(classmates_L)
['Michael', 'Bob', 'Tracy', 'Allen']
>>> classmates.append('Allen')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
>>>
?
List:
append()
>>> classmates_L.pop()
'Allen'
>>> print(classmates_L)
['Michael', 'Bob', 'Tracy']
>>> classmates_L.pop(2)
'Tracy'
>>> print(classmates_L)
['Michael', 'Bob']
>>>
>>>len(classmates_L)
2
>>> classmates_L[-1]
'Allen'
>>> classmates_L.insert(1,'Allen')
>>> print(classmates_L)
['Michael', 'Allen', 'Bob']
#避免歧義,定義一個元素的tuple,在元素后面要加上,
?
>>> name= ('Allen',)
>>> print(name)
('Allen',)
?
age = 20
if age >= 6:
print('teenager')
elif age >= 18:
print('adult')
else:
print('kid')
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print(sum)
sum = 0
list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for index in range(0,len(list)):
sum = sum + list[index]
print(sum)
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d['Michael']
95
d['Jack'] = 90
d['Jack']
90
d['Jack'] = 88
d['Jack']
88
d.pop('Michael')
95
print(d)
{'Tracy': 85, 'Bob': 75}
set和dict類似,也是一組key的集合,但不存儲value。由于key不能重復,所以,在set中,沒有重復的key。
?
要創建一個set,需要提供一個list作為輸入集合:
?
?
s = set([1, 2, 3])
s
{1, 2, 3}
s.add(4)
{1,2,3,4}
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
s1 & s2
{2, 3}
s1 | s2
{1, 2, 3, 4}
函數
def my_abs(x):
if x >= 0:
return x
else:
return -x
my_abs(-4)
4
python中函數的參數
只有位置參數: def func(a): pass
帶有默認參數 def func(a, b = 'default'): pass
帶有任意位置參數 def func(a, b = 'default', *args):pass
帶有任意鍵值的參數(關鍵字參數) def func(a, b = 'default',*args, **kwds):pass
==note==
位置參數是最基本的參數,它會跟所傳入的參數位置一一對應。
默認參數是為了簡化函數調用的方法,我們可以在定義中定義一個默認的值,以此對于某一類的參數,我們只需要傳入不同的位置參數.
def enroll(name, gender, age=6, city='Beijing'):
print('name:', name)
print('gender:', gender)
print('age:', age)
print('city:', city)
?
enroll('Sarah', 'F')
name: Sarah
gender: F
age: 6
city: Beijing
默認參數有幾個注意的地方:
有多個默認參數時,調用的時候,既可以按順序提供默認參數,比如調用enroll('Bob', 'M', 7)
,意思是,除了name
,gender
這兩個參數外,最后1個參數應用在參數age
上,city
參數由于沒有提供,仍然使用默認值。
也可以不按順序提供部分默認參數。當不按順序提供部分默認參數時,需要把參數名寫上。比如調用enroll('Adam', 'M', city='Tianjin')
,意思是,city
參數用傳進去的值,其他默認參數繼續使用默認值。
默認參數一定不能傳入可變元素。 因為默認參數在定義時候就已經確定了值,相當于已經給其分配了空間,當我們每一次調用的時候都會給那個空間中存入。
可變參數: 解決的問題是當你不確定要在函數中傳入多少個參數時候,你需要用到可變參數。
關鍵字參數: 相當于 userinfo
命名關鍵字參數: 相當于固定要傳進來的userinfo
命名關鍵字參數必須傳入參數名,這和位置參數不同。如果沒有傳入參數名,調用將報錯
如果要限制關鍵字參數的名字,就可以用命名關鍵字參數,例如,只接收city和job作為關鍵字參數。這種方式定義的函數如下:
?
def person(name, age, *, city, job):
print(name, age, city, job)
?
如果函數定義中已經有了一個可變參數,后面跟著的命名關鍵字參數就不再需要一個特殊分隔符*了:
?
def person(name, age, *args, city, job):
print(name, age, args, city, job)
在Python中定義函數,可以用必選參數、默認參數、可變參數、關鍵字參數和命名關鍵字參數,這5種參數都可以組合使用。但是請注意,參數定義的順序必須是:必選參數、默認參數、可變參數、命名關鍵字參數和關鍵字參數。
進階概念
切片
用來操作迭代對象,比如list,tuple,字符串等。有了切片操作,很多地方循環就不再需要了。Python的切片非常靈活,一行代碼就可以實現很多行循環才能完成的操作。
L = list(range(100))
print(L(:10))
print(L(10:20))
print(L(-10:))
print(L(0:10:2))
print(L(::5))
example:
冒泡
ListNumber = [4,2,51,212,34,99,110,122]
for x in ListNumber:
for y in ListNumber[ListNumber.index(x):]:
if x > y:
x, y = y, x
?
print(ListNumber)
?
[2, 4, 34, 51, 99, 110, 122, 212]
對于切片,我們需要參考 Python cookbook的建議,可以命名切片, 使得我們的程序中少點切片的硬編碼。
0123456789012345678901234567890123456789012345678901234567890'
record = '....................100 .......513.25 ..........'
糟糕的寫法
cost = int(record[20:23]) * float(record[31:37])
好的寫法
SHARES = slice(20, 23)
PRICE = slice(31, 37)
cost = int(record[SHARES]) * float(record[PRICE])
Note:
我們一旦命令了slice, 在任何地方都可以用到,包括列表的刪除,插入等
items = [0, 1, 2, 3, 4, 5, 6]
a = slice(2, 4)
items[2:4]
[2, 3]
items[a]
[2, 3]
items[a] = [10,11]
items
[0, 1, 10, 11, 4, 5, 6]
del items[a]
items
[0, 1, 4, 5, 6]
slice 有三個屬性, start,stop, step
slice 有一個方法indices(), 這個方法可以將所切片的范圍規定在給定字符串的范圍中,避免IndexError
?
列表生成器
列表生成式即List Comprehensions,是Python內置的非常簡單卻強大的可以用來創建list的生成式。
L = []
for x in range(1, 11):
... L.append(x * x)
...
L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
?
[x * x for x in L if x > 10]
[256, 625, 1296, 2401, 4096, 6561, 10000]
[x * x for x in L]
[1, 16, 81, 256, 625, 1296, 2401, 4096, 6561, 10000]
字典推導
字典推導式實際上跟 列表生成器是類似的, 代碼如下,實際上就是把 列表推導中的[]
換成{}
:
dic1 = {x: x * x for x in range(1,11)}
print dic1
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}
生成器
==方法1==
實際上跟 列表生成器是類似的, 代碼如下,實際上就是把 列表推導中的[]
換成()
, 在使用中用for 跟 next()方法取值。
Q:
為什么要用生成器
A:
通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那后面絕大多數元素占用的空間都白白浪費了。
所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出后續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱為生成器:generator。
G=(x+y for x in L for y in range(1,5) if x>y)
next(G)
12for x in G:
... print('Next:', x)
...
Next: 12
Next: 13
Next: 17
.
.
.
==方法2==
生成器的主要目的是構成一個用戶自定義的循環對象。
生成器的編寫方法和函數定義類似,==只是在return的地方改為yield==。生成器中可以有多個yield。當生成器遇到一個yield時,會暫停運行生成器,返回yield后面的值。當再次調用生成器的時候,會從剛才暫停的地方繼續運行,直到下一個yield。生成器自身又構成一個迭代器,每次迭代時使用一個yield返回的值。
def generate(endNum):
for x in range(0,endNum):
yield x*2
?
L = generate(10)
print(L)
for x in L:
print(x)
<generator object generate at 0x102183830> #這句說明通過generate函數之后是一個generator
0
2
4
6
8
10
12
14
16
18
迭代器
迭代器,廖學峰的教程中寫的很詳細
我們已經知道,可以直接作用于for
循環的數據類型有以下幾種:
一類是集合數據類型,如list
、tuple
、dict
、set
、str
等;
一類是generator
,包括生成器和帶yield
的generator function。
這些可以直接作用于for
循環的對象統稱為可迭代對象:Iterable
。
可以使用isinstance()
判斷一個對象是否是Iterable
對象:
而生成器不但可以作用于for
循環,還可以被next()
函數不斷調用并返回下一個值,直到最后拋出StopIteration
錯誤表示無法繼續返回下一個值了。
可以被next()
函數調用并不斷返回下一個值的對象稱為迭代器:Iterator
。
可以使用isinstance()
判斷一個對象是否是Iterator
對象:
高階函數, Map, filter , sorted等, 匿名函數
高階函數:
對于python, 函數本身也可以賦值給變量,即:變量可以指向函數。 既然變量可以指向函數,函數的參數能接收變量,那么一個函數就可以接收另一個函數作為參數,這種函數就稱之為==高階函數==。
example:
def higherFunc(x, y, f):
return f(x)+f(y)
?
print(higherFunc(1,-2,abs))
3
Map:
在stackover flow 上 有人這么總結Map
map(f, iterable)
?
基本上等于:
?
[f(x) for x in iterable]
example
?
L = map(TestMap,[88,11,33])
list(L)
[10088, 10011, 10033]
Sorted:
排序 :廖學峰
此外,sorted()
函數也是一個高階函數,它還可以接收一個key
函數來實現自定義的排序,例如按絕對值大小排序:
?
from operator import itemgetter
rows = [
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
?
sorwRows1 = sorted(rows, key= itemgetter('uid')) # itemgetter: operator模塊提供的itemgetter函數用于獲取對象的哪些維的數據,
print('sorted ROWS :%s' % sorwRows1)
?
?
?
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
sortL = sorted(L, key = itemgetter(0), reverse = True)
print(sortL)
匿名函數
關鍵字lambda
表示匿名函數,冒號前面的x
表示函數參數。
匿名函數有個限制,就是只能有一個表達式,不用寫return
,返回值就是該表達式的結果。
def build(x, y):
return lambda: x * x + y * y
裝飾器(==語法糖:@==)
目前最清晰的入門博客
假設我們要增強now()
函數的功能,比如,在函數調用前后自動打印日志,但又不希望修改now()
函數的定義,這種在代碼運行期間動態增加功能的方式,稱之為“裝飾器”(Decorator)。
==本質上,decorator就是一個返回函數的高階函數。==
裝飾器其實也就是一個函數,一個用來包裝函數的函數,返回一個修改之后的函數對象,將其重新賦值原來的標識符,并永久喪失對原始函數對象的訪問
Note:
==語法糖:==
語法糖(Syntactic sugar),也譯為糖衣語法,是由英國計算機科學家彼得·約翰·蘭達(Peter J. Landin)發明的一個術語,指計算機語言中添加的某種語法,這種語法對語言的功能并沒有影響,但是更方便程序員使用。通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯的機會。