Python 學習筆記(二)[語法進階]
阿新 • • 發佈:2018-11-27
深淺拷貝
引用
list_1 = [1,2,3]
list_2 = list_1
list_1 修改其中元素時,list_2 也被影響
淺拷貝
list_1 = [1,2,3,['a','b','c']]
list_2 = list1[:]
只拷貝了最外層元素,修改 list_1 中的 1 時,list_2 不受影響,修改 list_1 中的 a 時,list_2 受影響
深拷貝
import copy
list_1 = [1,2,3,['a','b','c']]
list_2 = copy.deepcopy(list_1)
如何修改 list_1 中的元素,list_2 都不受影響
字典、集合
字典
- 字典中的資料在記憶體裡是無序的(不能使用索引和切片)
- key 值會進行 hash 運算(所以 key 不能使用可變資料型別),生成雜湊表(相當於目錄),所以訪問效率高
- 建立
mydict = {1:'a',2:'b'}
mydict = dict(([1,'a'],[2,'b']))
# 批量建立 key,無法單獨分配 value
mydict = dict.fromkeys([1,2,3],'a')
mydict = dict.fromkeys('abc',1)
- 訪問
mydict.keys() mydict.values() # 判斷 key 是否存在,再取 value if 1 in mydict mydict[1] # 迴圈輸出字典中的 key 和 value for key in mydict: print(key,':',mydict[key])
- 刪除
del mydict[1]
# 用一個變數儲存刪除的 value
var = mydict.pop(1)
# 清空
mydict.clear()
集合
- 可變集合 → set,不可變集合 → frozenset,不支援索引訪問
- 元素值會進行 hash 運算(所以元素的值不能是可變資料),且元素不能重複
- 建立
# 可變
myset = {1,2,3}
myset = set([1,2,3])
# 不可變
myset = frozenset([1,2,3])
- 訪問
for var in myset: print(var)
- 更新
# 直接新增一個元組
myset.add(('a','b','c'))
# 把元組拆成多個元素
myset.update(('a','b','c'))
- 刪除
myset.remove(1)
myset.discard(1)
var = myset.pop(1)
myset.clear()
- 關係
myset1 = {1,2,3}
myset2 = {1,2,3,'a'}
# 判斷是否為子集
# True
myset1 < myset2
# False
myset1.add('b')
myset1 < myset2
myset1 = {1,2,3,'a'}
myset2 = {1,2,3,'b'}
# 交集:{1,2,3}
myset1 & myset2
# 並集:{1,2,3,'a','b'}
myset1 | myset2
# 補集:{'a'}
myset1 - myset2
# 對稱差分:{'a','b'}
myset1 ^ myset2
內建函式
字串
- 大小寫轉換
函式 | 意義 |
---|---|
string.lower() | 字母轉換成小寫 |
string.upper() | 字母轉換成大寫 |
string.swapcase() | 字母大寫轉換成小寫,小寫轉換成大寫 |
string.title() | 首字母轉化成大寫,其它字母轉換成小寫,多段都改 |
string.capitalize() | 首字母轉化成大寫,其它字母轉換成小寫,只改第一段 |
- 搜尋
函式 | 意義 |
---|---|
string.find(target,start,end) | 在 string 的 start 到 end 中,查詢 target 的位置,如果沒有 → 返回 -1 |
string.index(target,start,end) | 在 string 的 start 到 end 中,查詢 target 的位置,如果沒有 → 報錯 |
string.count(target) | 統計 target 在 string 中出現的次數 |
string.startswith(target) | 判斷 string 是否以 target 開始 |
string.endswith(target) | 判斷 string 是否以 target 結尾 |
- 替換
函式 | 意義 |
---|---|
string.replace(str1,str2,[num=string.count(str1)]) | 將 str1 替換為 str2,num 為替換次數,預設為 str1 出現的次數 |
string.strip(chr) | 在 string 的開頭和結尾刪除 chr |
string.lstrip() / string.rstrip() | 刪除 string 開頭 / 末尾的空白字元(空格、\n、\t) |
- 分割、組合
函式 | 意義 |
---|---|
string.split(chr,num=string.count(str)) | 以 chr 為分割符分割 string,結果儲存在列表中,如果指定 num,則只分割 num 次 |
chr.join(str.[list,tuple]) | 以 chr 為連線符,拼接字串 |
- 判斷
函式 | 意義 |
---|---|
string.isdigit() | 是否只包含數字 |
string.islower() | 字母是否全為小寫 |
string.isupper() | 字母是否全為大寫 |
string.isspace() | 是否只包含空白字元 |
- 列表
函式 | 意義 |
---|---|
list.append(obj) | 在列表尾部追加元素 |
list.count(obj) | 返回一個物件出現的次數 |
list.extend(seq) | 把序列 seq 中的內容加入到列表中 |
list.insert(index,obj) | 在 index 位置插入 obj,原位置內容後移 |
list.pop(index) | 刪除並返回物件,預設是最後一個 |
list.reverse() | 反轉列表 |
- 元組
函式 | 意義 |
---|---|
tuple.index(obj,start=0,end=len(string)) | 檢查 obj 是否包含在 tuple 中 |
tuple.count(obj) | 返回一個物件出現的次數 |
系統
函式 | 意義 |
---|---|
enumerate(iter) | 傳入一個可迭代的引數,返回 enumerate 物件,也是一個迭代器,是 iter 中每個元素的 index 和 item 值 |
len(seq) | 返回 seq 的長度 |
max(iter,key=None) / min(iter,key=None) | 取最大 / 小值,key 引數為比較規則,如 key = lambda x:x[1],說明要比較 [1] 位置的值 |
reversed(seq) | 傳入一個序列,返回逆序訪問的迭代器 |
sorted(iter,cmp=None,key=None) | 傳入一個可迭代物件,返回一個有序列表,可傳入排序方式 |
sum(seq,init=0) | 返回列表和 init 的總和 |
zip(it0,it1,…itN) | 對應索引上的值組合成一個新元素,直到最短的引數被用完,返回一個列表 |
map(func,seq) | 第一個引數可以是一個函式物件,第二個引數是一個序列,函式依次作用在序列的每個元素上 |
reduce:把一個函式作用在一個序列上,這個函式必須接收兩個引數,函式的結果會與下一個元素做累積計算
from functools import reduce
def func(x,y):
return x*y
mylist = [1,2,3]
reduce(func,mylist)
推導式
列表
mylist = [1,2,3,4,5]
# [1,4,16,25]
new_list = [var*var for var in mylist if var != 3]
# 生成器
new_list = (var*var for var in mylist if var != 3)
new_list.__next__()
字典
mylist = [1,2,3]
# {2:'a',3:'a'}
mydict = {var:'a' for var in mylist if var > 1}
集合
mylist = [1,2,3]
# {2,3,4}
myset = {var+1 for var in mylist}
檔案操作
開啟
# file:檔案路徑 + 名稱,mode:操作型別(r:讀、w:寫、a:追加,帶加號表示讀寫)
open(file,mode='r')
操作
- 讀
# num:要讀取的位元組數
mystr = myfile.read(num)
修改指標的位置,offset:偏移量,whence:從何處偏移(0:檔案開頭、1:當前位置、2:檔案末尾)
mystr = myfile.seek(offset,whence)
# 讀一行
mystr = myfile.readline()
# 讀多行
mylist = myfile.readlines()
# for 按行讀
mylist = []
for var in myfile:
mylist.append(var)
- 寫
# 寫入,會覆蓋上一次寫的內容
myfile = open('1.txt','w')
myfile.write('abc\n')
# 追加
myfile = open('1.txt','a')
myfile.write('abc')
# 把記憶體中對檔案的修改放到磁碟上
myfile.flush()
# 關閉檔案
myfile.close()
# 備份檔案
myfile1 = open('1.txt','r')
myfile2 = open('2.txt','a')
mylist = myfile1.readlines()
myfile2.writelines(mylist)
myfile1.close()
myfile2.close()
- 加密
# 讀,加密
import random
secretlist = ['!','@','#','$','%','^','&','*','=','<','~']
info_file = open('info.txt','r')
mylist = []
for var in info_file.read():
index = random.randint(0,9)
var = var + secretlist[index]
mylist.append(var)
info_file.close()
# 寫
info_file = open('info.txt','w')
new_str = ''.join(mylist)
info_file.write(new_str)
info_file.close()
- 註冊
account_file = open('register.txt','a+')
while True:
has_account = False
account = input('請輸入賬號:')
# 移動讀寫指標到檔案開頭
account_file.seek(0,0)
for var in account_file:
file_account = var.split(':')[0]
if account == file_account:
print('賬號已被註冊!')
has_account = True
break
if has_account:
continue
# 接收密碼,儲存
password = input('請輸入密碼:')
new_account = account + ':' + password + '\n'
account_file.write(new_account)
account_file.close()
break
- 登入
account_file = open('account_info.txt','r')
while True:
has_login = False
account = input('請輸入賬號:')
account_file.seek(0,0)
for var in account_file:
if has_login:
break
file_account = var.split(':')[0]
if account == file_account:
index = 3
while index > 0:
password = input('請輸入密碼:')
file_password = var.split(':')[1].strip()
if password == file_password:
print('登入成功!')
has_login = True
break
else:
index -= 1
print('密碼錯誤!你還有%d次機會' % index)
if has_login:
account_file.close()
break
print('請重新登入!')