python之路-Day2 自記筆記
本節內容
- 列表、元組操作
- 字串操作
- 字典操作
- 集合操作
- 檔案操作
- 字元編碼與轉碼
一、模組初識
getpass模組在Day-1中已經使用過
模組分兩種,標準庫與第三方庫,標準庫不需要安裝,直接匯入就可以使用,第三方庫需要下載安裝,比如jongo
初識下兩個標準庫
1.sys模組
import sys
print(sys.path) #列印環境變數
執行後會輸出一些路徑,這裡就顯示了python的標準庫與第三方庫存放模組的路徑
一般 lib存放系統自帶的模組,site-packages存放第三方模組;
print(sys.argv)
會輸出當前python檔案的相對路徑,以列表的形式出現
2.os模組
在python中呼叫shell,在系統中建立檔案,做操作,這些就是os模組的作用,先學這兩個作用
1 import os 2 cmd_res = os.system("dir") #執行命令,不儲存結果 3 print("---->",cmd_res) 4 5 cmd_res2 = os.popen("dir").read() #執行命令,並用read在記憶體裡把結果取出 6 print("---->",cmd_res2) 7 8 cmd_res3 = os.mkdir("new_dir") #在當前路徑建立一個新的目錄
3.第三方庫
自己寫的模組要記得放在當前路徑或者site-packages下
二、什麼是pyc
在剛才呼叫了自己做的第三方庫之後,出現了pycache,裡面有pyc檔案
1. Python是一門解釋型語言?
我初學Python時,聽到的關於Python的第一句話就是,Python是一門解釋性語言,我就這樣一直相信下去,直到發現了*.pyc檔案的存在。如果是解釋型語言,那麼生成的*.pyc檔案是什麼呢?c應該是compiled的縮寫才對啊!
為了防止其他學習Python的人也被這句話誤解,那麼我們就在文中來澄清下這個問題,並且把一些基礎概念給理清。
2. 解釋型語言和編譯型語言
計算機是不能夠識別高階語言的,所以當我們執行一個高階語言程式的時候,就需要一個“翻譯機”來從事把高階語言轉變成計算機能讀懂的機器語言的過程。這個過程分成兩類,第一種是編譯,第二種是解釋。
編譯型語言在程式執行之前,先會通過編譯器對程式執行一個編譯的過程,把程式轉變成機器語言。執行時就不需要翻譯,而直接執行就可以了。最典型的例子就是C語言。
解釋型語言就沒有這個編譯的過程,而是在程式執行的時候,通過直譯器對程式逐行作出解釋,然後直接執行,最典型的例子是Ruby。
通過以上的例子,我們可以來總結一下解釋型語言和編譯型語言的優缺點,因為編譯型語言在程式執行之前就已經對程式做出了“翻譯”,所以在執行時就少掉了“翻譯”的過程,所以效率比較高。但是我們也不能一概而論,一些解釋型語言也可以通過直譯器的優化來在對程式做出翻譯時對整個程式做出優化,從而在效率上超過編譯型語言。
此外,隨著Java等基於虛擬機器的語言的興起,我們又不能把語言純粹地分成解釋型和編譯型這兩種。
用Java來舉例,Java首先是通過編譯器編譯成位元組碼檔案,然後在執行時通過直譯器給解釋成機器檔案。所以我們說Java是一種先編譯後解釋的語言。
3. Python到底是什麼
其實Python和Java/C#一樣,也是一門基於虛擬機器的語言,我們先來從表面上簡單地瞭解一下Python程式的執行過程吧。
當我們在命令列中輸入python hello.py時,其實是激活了Python的“直譯器”,告訴“直譯器”:你要開始工作了。可是在“解釋”之前,其實執行的第一項工作和Java一樣,是編譯。
熟悉Java的同學可以想一下我們在命令列中如何執行一個Java的程式:
javac hello.java
java hello
只是我們在用Eclipse之類的IDE時,將這兩部給融合成了一部而已。其實Python也一樣,當我們執行python hello.py時,他也一樣執行了這麼一個過程,所以我們應該這樣來描述Python,Python是一門先編譯後解釋的語言。
4. 簡述Python的執行過程
在說這個問題之前,我們先來說兩個概念,PyCodeObject和pyc檔案。
我們在硬碟上看到的pyc自然不必多說,而其實PyCodeObject則是Python編譯器真正編譯成的結果。我們先簡單知道就可以了,繼續向下看。
當python程式執行時,編譯的結果則是儲存在位於記憶體中的PyCodeObject中,當Python程式執行結束時,Python直譯器則將PyCodeObject寫回到pyc檔案中。
當python程式第二次執行時,首先程式會在硬碟中尋找pyc檔案,如果找到,則直接載入,否則就重複上面的過程。
所以我們應該這樣來定位PyCodeObject和pyc檔案,我們說pyc檔案其實是PyCodeObject的一種持久化儲存方式。
三、資料型別初識
數字
2 是一個整數的例子。
長整數 不過是大一些的整數。
3.23和52.3E-4是浮點數的例子。E標記表示10的冪。在這裡,52.3E-4表示52.3 * 10-4。
(-5+4j)和(2.3-4.6j)是複數的例子,其中-5,4為實數,j為虛數,數學中表示覆數是什麼?。
int(整型)
在32位機器上,整數的位數為32位,取值範圍為-2**31~2**31-1,即-2147483648~2147483647
在64位系統上,整數的位數為64位,取值範圍為-2**63~2**63-1,即-9223372036854775808~9223372036854775807
long(長整型)
跟C語言不同,Python的長整數沒有指定位寬,即:Python沒有限制長整數數值的大小,但實際上由於機器記憶體有限,我們使用的長整數數值不可能無限大。
注意,自從Python2.2起,如果整數發生溢位,Python會自動將整數資料轉換為長整數,所以如今在長整數資料後面不加字母L也不會導致嚴重後果了。
python3無論存多大都是整形,沒有長整型了,只有int,沒有long
float(浮點型)
先掃盲 http://www.cnblogs.com/alex3714/articles/5895848.html
浮點數用來處理實數,即帶有小數的數字。類似於C語言中的double型別,佔8個位元組(64位),其中52位表示底,11位表示指數,剩下的一位表示符號。
complex(複數)
複數由實數部分和虛數部分組成,一般形式為x+yj,其中的x是複數的實數部分,y是複數的虛數部分,這裡的x和y都是實數。
注:Python中存在小數字池:-5 ~ 257
2、布林值
真或假
1 或 0
3、字串
"hello world"
萬惡的字串拼接:
python中的字串在C語言中體現為是一個字元陣列,每次建立字串時候需要在記憶體中開闢一塊連續的空,並且一旦需要修改字串的話,就需要再次開闢空間,萬惡的+號每出現一次就會在內從中重新開闢一塊空間。
4.byte型別與str相互轉換
四、三元運算
1 a,b,c = 1,3,5 2 3 d = a if a > b else c 4 print(d) 5 d = a if a < b else c 6 print(d)
d的值可能是1,也可能是5,看設定的條件而定,這就是三元運算
五、資料運算
算數運算:
比較運算:
賦值運算:
邏輯運算:
成員運算:
身份運算:
位運算:
1 #!/usr/bin/python 2 3 a = 60 # 60 = 0011 1100 4 b = 13 # 13 = 0000 1101 5 c = 0 6 7 c = a & b; # 12 = 0000 1100 8 print "Line 1 - Value of c is ", c 9 10 c = a | b; # 61 = 0011 1101 11 print "Line 2 - Value of c is ", c 12 13 c = a ^ b; # 49 = 0011 0001 #相同為0,不同為1 14 print "Line 3 - Value of c is ", c 15 16 c = ~a; # -61 = 1100 0011 17 print "Line 4 - Value of c is ", c 18 19 c = a << 2; # 240 = 1111 0000 20 print "Line 5 - Value of c is ", c 21 22 c = a >> 2; # 15 = 0000 1111 23 print "Line 6 - Value of c is ", c
*按位取反運算規則(按位取反再加1) 詳解http://blog.csdn.net/wenxinwukui234/article/details/42119265
運算子優先順序:
六、進位制
- 二進位制,01
- 八進位制,01234567
- 十進位制,0123456789
- 十六進位制,0123456789ABCDEF 二進位制到16進位制轉換http://jingyan.baidu.com/album/47a29f24292608c0142399cb.html?picindex=1
計算機記憶體地址和為什麼用16進位制?
為什麼用16進位制
1、計算機硬體是0101二進位制的,16進位制剛好是2的倍數,更容易表達一個命令或者資料。十六進位制更簡短,因為換算的時候一位16進位制數可以頂4位2進位制數,也就是一個位元組(8位進位制可以用兩個16進製表示)
2、最早規定ASCII字符集採用的就是8bit(後期擴充套件了,但是基礎單位還是8bit),8bit用2個16進位制直接就能表達出來,不管閱讀還是儲存都比其他進位制要方便
3、計算機中CPU運算也是遵照ASCII字符集,以16、32、64的這樣的方式在發展,因此資料交換的時候16進位制也顯得更好
4、為了統一規範,CPU、記憶體、硬碟我們看到都是採用的16進位制計算16進位制用在哪裡
1、網路程式設計,資料交換的時候需要對位元組進行解析都是一個byte一個byte的處理,1個byte可以用0xFF兩個16進位制來表達。通過網路抓包,可以看到資料是通過16進位制傳輸的。
2、資料儲存,儲存到硬體中是0101的方式,儲存到系統中的表達方式都是byte方式3、一些常用值的定義,比如:我們經常用到的html中color表達,就是用的16進位制方式,4個16進位制位可以表達好幾百萬的顏色資訊。
七、列表與元祖
一般我們要存資料用變數存,一個是整數,一個是字串
如果要存100人的名字呢?
一個人名一個變數嗎?
太LOW了,如果你想存很多的字串資訊,這裡就引出了列表
1 # Auther: Tank Jarvis 2 names = ["zhangsan","lisi","wangwu","maliu"] 3 print(names[0]) #取第1個值 4 print(names[1:3]) #取第2個和第3個的值,起始位置包括,結束為止往後錯一位 5 print(names[0:3]) #也叫切片 6 print(names[-1]) #倒著數是從-1開始 7 print(names[-2:]) #取值的順序都是從左往右 8 print(names[:2]) #開頭和結尾可省略 9 names.append("Meiguoduizhang") #追加在最後 10 names.insert(1,"Heiguafu") #插入到哪個位置就寫幾 11 names.insert(3,"Zhizhuxia") #插入到哪個位置就寫幾 12 print(names) #插入只能一個一個來 13 names[2] = "Ironman" #更改 14 15 names.remove("Meiguoduizhang") #按照值刪除 16 del names[-1] #按照下標刪除 17 names.pop() #沒輸入下標,pop就是刪除最後一個值 18 19 #根據值找下標:index 20 print(names.index("Heiguafu")) 21 print(names[names.index("Heiguafu")]) 22 23 #值出現重複的時候,計數重複數量 24 names.append("Ironman") 25 print(names.count("Ironman")) 26 27 #反轉 28 names.reverse() 29 print(names) 30 31 #排序:先特殊字元,再數字,再大寫,再小寫,遵循ACSII碼排序規則 32 names.sort() 33 print(names) 34 35 #擴充套件吸收其他列表 36 names2 = [1,2,3,4] 37 names.extend(names2) 38 print(names) 39 print(names2) 40 41 #刪掉names2這個變數 42 del names2 43 print(names2) 44 45 #清空列表 46 names.clear() 47 print(names)
copy單獨講一下:注意深層次的列表copy的是記憶體指標,值會跟著變,這樣也叫淺copy
1 # Auther: Tank Jarvis 2 #COPY的用法 3 names = ["zhangsan","lisi","wangwu","maliu"] 4 5 names2 = names.copy() 6 print(names,names2) 7 8 names[1] = "李四" 9 print(names,names2) 10 11 names.insert(3,[1,2,"tank"]) 12 names3 = names.copy() 13 print(names,names3) 14 15 names[3][0] = "Jarvis" 16 print(names,names3) 17 #第二層列表被複制後,源names改第二層列表也會使得names3的第二層 18 #列表也會跟著更改,因為下一層列表copy的是記憶體指標,會根據記憶體的值改變
怎麼做到深copy 匯入copy模組,使用copy.deepdopy()
1 # Auther: Tank Jarvis 2 3 names = ["zhangsan","lisi","wangwu","maliu"] 4 5 #深copy 6 import copy 7 names.append([1,2,"tank"]) 8 names2 = copy.deepcopy(names) 9 print(names,names2) 10 11 names[-1][0] = "Jarvis" 12 print(names,names2)
迴圈和步長切片
1 # Auther: Tank Jarvis 2 3 names = ["zhangsan","lisi","wangwu","maliu"] 4 #迴圈 5 for i in names: 6 print(i) 7 8 #跳著切片 步長切片 9 print(names[0:-1:2]) 10 print(names[::2])
列表個字典在開發中最最常用的資料型別
元祖就是列表,但元祖是隻讀的,只能切片,只能查,不可變寫法不是[],而是(),小括號
只有兩個方法:count,index
1 # Auther: Tank Jarvis 2 names = ("zhangsan","lisi","wangwu","maliu","tank") 3 print(names.count("zhangsan")) #計數 4 print(names.index("maliu")) #根據值查下標
做個練習
程式:購物車程式
需求:
- 啟動程式後,讓使用者輸入工資,然後列印商品列表
- 允許使用者根據商品編號購買商品
- 使用者選擇商品後,檢測餘額是否夠,夠就直接扣款,不夠就提醒
- 可隨時退出,退出時,列印已購買商品和餘額
1 # Auther: Tank Jarvis 2 salary = input("Please input your balance: ") 3 product_list = [ 4 ("iphone",10000), 5 ("mac",12000), 6 ("iwatch",5800), 7 ("coofee",66), 8 ("bike",800) 9 ] 10 buy_list = [] 11 if salary.isdigit(): 12 salary = int(salary) 13 while True: 14 # for iterm in product_list: 15 # print(product_list.index(iterm),iterm) 16 for index,item in enumerate(product_list): 17 print(index,item) 18 user_choice = input("Please choose the num of product :" ) 19 if user_choice.isdigit(): 20 user_choice = int(user_choice) 21 if user_choice >= 0 and user_choice < len(product_list): 22 p_item = product_list[user_choice] 23 if p_item[1] <= salary: 24 buy_list.append(p_item) 25 salary -= p_item[1] 26 print("Added %s into shopping cart, your current balance is %s" %(p_item,salary)) 27 else: 28 print("Your current balance is not enough, it is only %s" % (salary)) 29 else: 30 print("your choice is not valid.") 31 elif user_choice == "q": 32 print("---------shopping list---------") 33 for p in buy_list: 34 print(p) 35 print("Your current salary is ",salary) 36 exit() 37 else: 38 print("invalid option")
八、集合、字典
九、字串的操作
1 # Auther: Tank Jarvis 2 3 name = "my name is tank" 4 5 print(name.capitalize()) #首字母大寫 6 print(name.count("a")) #計數 7 print(name.center(50,"-")) #優化顯示 8 print(name.encode()) #把字串轉成二進位制 9 print(name.endswith("ank")) #判斷一個字串以什麼結尾 10 print(name.expandtabs()) #轉換tab鍵成空格 11 print(name.find("tank")) #字串切片 12 print(name.format()) #匹配賦值 13 print(name.isalnum()) #判斷是否為阿拉伯英文與數字,其他字元會返回False 14 print(name.isalpha()) #判斷是否為純英文 15 print(name.isdecimal()) #判斷是否為十進位制 16 print(name.isdigit()) #判斷是否為整數,常用 17 print(name.isidentifier()) #判斷是否為合法的識別符號,是不是一個合法的變數名 18 print(name.islower()) #判斷是不是小寫 19 print(name.isnumeric()) #判斷是不是一個整數 20 print(name.isspace()) #判斷是不是空格 21 print(name.istitle()) #判斷每個單詞的首字母是否大寫 22 print(name.isupper()) #判斷是不是全大寫 23 print("+".join(["1","2","3"])) #把一個設定的字元插入到列表中的每個間隙形成一個字串 24 print(name.ljust(50,"*")) #總長50,在後面用*補位 25 print(name.rjust(50,"-")) #總長50,在後面用-補位 26 print(name.lower()) #把大寫變小寫 27 print(name.upper()) #把小寫變大寫 28 print(name.lstrip()) #strip去掉空格和回車 l去除左邊 r去除右邊 29 print(name.rstrip()) 30 print(name.strip()) 31 p = str.maketrans("abcdef","123456") #maketrans可以做對應的規則替換 32 print("hello, my name is alex".translate(p)) 33 print(name.replace("m","123",1))#把變數裡的字母替換掉 34 print(name.rfind("m")) #匹配最右邊的下標並返回 35 print(name.split("n")) #把字串按照空格分成列表,也可以按照其他資料分 36 print(name.splitlines()) #把字串按照 行 分成列表 37 print('Alex Li 123'.swapcase()) #英文字母大寫變小寫,小寫變大寫 38 print(name.title()) #每個英文字母都大寫