1. 程式人生 > >Python 學習筆記(二)[語法進階]

Python 學習筆記(二)[語法進階]

深淺拷貝

引用

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('請重新登入!')