python27期day12:推導式、內置函數、高階函數、匿名函數、做業題

  一、推導式:作一些有規律的數據結構python

列表推導式:面試

      普通循環模式:數組

      [加工後的變量 for 循環]數據結構

      示例一:print([i for i in range(1,51)])
      結果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
      示例二:print([i for i in range(1,51,2)])
      結果:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]
      格式化:
      print([f"python{i}期" for i in range(1,51)])
      篩選模式:
      [加工後的變量 for循環 加工條件]
      print([i for i in range(1,51) if i > 25])
      結果:[26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
for循環兩個數的和:
lst = []
for i in range(2):
  for j in range(2):
    lst.append(i+j)
print(lst)
結果:[0, 1, 1, 2]
列表推導式兩個數的和(推導式最多建議使用三層):
print([i + j for i in range(2) for j in range(2)])
結果:[0, 1, 1, 2]
字典推導式:
print({i:i+1 for i in range(3)})
結果:{0: 1, 1: 2, 2: 3}
集合推導式:
print({f"{i}:{i+1}" for i in range(3)})
結果:{'1:2', '0:1', '2:3'}
{加工後的變量:加工後的變量 for循環 加工條件}
print({i:i+1 for i in range(3) if i >= 0})
結果:{0: 1, 1: 2, 2: 3}
推導式:用在哪?簡化代碼、提升可讀性
生成一些有規律的數據、生成的數據較大時建議使用生成器推導式
for循環索引推導式:
s = "alex,meet"
count = 0
for i in s:
if i == "e":
print(count)
count += 1
結果:2
   6
   7
len索引推導式:
print([i for i in range(len(s)) if s[i] == "e"])
列表嵌套推導式:
names = [['Tom','Billy','Jefferson','Andrew','Wesley','Steven','Joe'],
['Alice','Jill','Ana','Wendy','Jennifer','Sherry','Eva']
]
寫法一:
for i in names:
for em in i:
if "e" in em:
print(em)
寫法二:
print([em for i in names for em in i if "e" in em])
偶數推導式:
print([i for i in range(30) if i % 3 is 0])
結果:[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
過濾和轉大寫:
l = ['wusir','laonanhai','aa','b','taibai']
print([i.upper() for i in l if len(i) > 3])
結果:['WUSIR', 'LAONANHAI', 'TAIBAI']
二、生成器表達式和列表推導式的語法上如出一轍、只是把[]換成()就好了、例如將10之內全部數的平方放到一個生成器表達式中:
gen = (i**2 for i in range(10))
print(gen)               #獲得生成器對象
print(gen.__next__())        #生成一個數
print(next(gen))           #再次生成一個數
生成器表達式進行篩選:
gen = (i for i in range(1,100) if i % 3 == 0)
for num in gen:
print(num)
三、生成器表達式和列表推導式的區別?
列表推導式比較耗內存、全部數據一次性加載到內存、而生成器表達式遵循迭代器協議、逐個產生元素。
獲得的值不同、列表推導式獲得的是一個列表、生成器表達式獲取的是一個生成器
列表推導式一目瞭然、生成器表達式只是一個內存地址
不管是生成器表達式仍是列表推導式、只是python提供了一個相對簡單的構造方式、由於使用推導式很是簡單、推導式只能構建相對複雜的而且有規律的對象
對於沒有什麼規律、並且嵌套層數比較多不建議使用推導式構建
生成器的惰性機制:生成器只有在訪問的時候才取值、
四、內置函數:python寫了不少功能避免重複造輪子
一帶而過:
all()  #判斷元素是否都爲true
any()  #判斷元素是否有一個是true就是true
bytes() #字符串轉字節
callable("你好")  #判斷是否可調用
chr()  #根據當前編碼查看對應的內容
complex()  #查看複數
divmod()  #獲取是元組、第一個是商、第二個是餘數
eval()  #禁用
exec()  #禁用
frozenset()  #凍結集合
globals()
hash()  #有值是不可變的數據類型
help()  #查看方法的幫助信息
id()   
input()
int()
iter()
locals()
next()
oct()  #十進制轉成八進制
bin()  #十進制轉成二進制
hex()  #十進制轉成十六進制
print(int("0x1e",16))  #十六進制轉成十進制
ord()  #根據值查看當前編碼
pow()  #冪
repr()  #原形畢露
round()  #保留小數位
重點記住:
abs()  #絕對值
format()  #格式化
enumerate()  #枚舉、自動獲取元素下標、自動計數
filter()
map()
max()
min()
open()
range()
print()
len()
list()
dict()
str()
float()
reversed()
set()
sorted()  #排序
sum()
tuple()
type()
zip()
dir()  #查看當前對象都有什麼方法
將來會用:
classmethod()
delattr()
getattr()
hasattr()
issubclass()
isinstance()
object()
property()
selattr()
staticmethod()
super()
五、高階函數:
filter(規則函數,可迭代對象)、
map(規則函數,可迭代對象,可迭代對象)、
max()、
min()、
reversed(可迭代對象)、
sorted(可迭代對象,key = 規則函數)、
reduce(累加函數,可迭代對象)、
zip()、
六、匿名函數,顧名思義就是沒有名字的函數,那麼什麼函數沒有名字呢?這個就是咱們之後面試或者工做中常常用匿名函數 lambda,也叫一句話函數。
如今有一個需求:大家寫一個函數,此函數接收兩個int參數,返回和值。
def func(a,b):
    return a+b
print(func(3,4))
那麼接下來咱們用匿名函數完成上面的需求:
func = lambda a,b: a+b
print(func(3, 4))  # 7
語法:

​ 1)此函數不是沒有名字,他是有名字的,他的名字就叫作lambdaapp

​ 2)lambda 是定義匿名函數的關鍵字,至關於函數的def.函數

​ 3)lambda 後面直接加形參,形參加多少均可以,只要用逗號隔開就行。  ui

​ 4)返回值在冒號以後設置,返回值和正常的函數同樣,能夠是任意數據類型。(可是想要返回多個元素要以容器的形式返回)編碼

​ 5)匿名函數無論多複雜.只能寫一行.且邏輯結束後直接返回數據spa

寫匿名函數:接收一個可切片的數據,返回索引爲0與2的對應的元素(元組形式)。code

func = lambda x:(x[0],x[2])
print(func('afafasd'))
七、匿名函數三元表達式:
func = lambda x,y: x if x > y else y
print(func(3,100))
結果:100
八、匿名函數lambda和有名函數def:
f = lambda a,b:a + b
print(f(1,2))
# 結果3
def func(a,b):
c = a + b
return c
print(func(1,2))
# 結果3
lambda和def是同樣的、
a,b和(a,b)是同樣的
:a + b和return a + b是同樣的
冒號前面叫作形參、冒號後面叫作返回值
形參能夠接受位置參數、動態位置、默認、動態關鍵字參數、形參不可不寫
返回值只能返回一個數據、返回值必須寫
返回值是多個時用括號包起來
print(f.__name__)--查看函數名
九、lambda函數舉例:
# g = [lambda i:i+1 for i in range(3)]  #首先這是列表推導式、循環三圈獲得三個匿名函數lambda、例如定義是L、第二圈仍是L、第三圈仍是L、函數體中存的是代碼、也能夠把for i定義成for j、整個推完以後有三個函數的內存地址定義爲g、
# print([em(3) for em in g])         #而後循環三個內存地址定義em、加括號運行、命名參數三、獲得結果3+1=四、第二圈仍是四、第三圈仍是4
#上面兩行代碼拆解:
lst = []
for i in range(3): #for循環0到3
def func(i): #形參是i也就是0、一、2
return i + 1 #返回值是循環的每一個值加1
lst.append(func) #往空列表裏面增長func函數的內存地址
print(lst) #打印出lst列表裏面的3個func函數的內存地址
# 結果:[<function func at 0x00000000001E2EA0>, <function func at 0x0000000001E9AB70>, <function func at 0x0000000001E9AA60>]

new_lst = [] #新建空列表new_lst
for em in lst: #循環lst列表裏面的3個func函數的內存地址
new_lst.append(em(3)) #空列表裏面增長3個func函數的內存地址運行結果、說白了在調用func、可是func函數須要參數i、因此增長em裏面增長一個參數3
print(new_lst) #打印new_lst列表
# 結果:[4, 4, 4]
十、lambda函數舉例二:
# g = (lambda i:i+1 for j in range(3))
# print([em(3) for em in g])
#上面兩行代碼拆解:
def foo():
for j in range(3):
def func(i):
return i + 1
yield func
g = foo()
# print(g) #獲得生成器
# print(next(g)) #獲得函數的內存地址

lst = []
for i in g:
lst.append(i(3))
print(lst)
結果:[4,4,4]
十一、小括號是生成器推導式、中括號是列表推導式
十二、lambda函數舉例三:
# g = [lambda :i+1 for i in range(3)]
# print([em() for em in g])
#上面兩行代碼拆解:
g = []
for i in range(3):
def func():
return i + 1
g.append(func)
print(g)

new_lst = []
for em in g:
new_lst.append(em())
print(new_lst)
結果:[3,3,3]
1三、lambda函數舉例四:
g = (lambda :i+1 for i in range(3))
print([em() for em in g])
#上面兩行代碼拆解:
def foo():
for i in range(3):
def func():
return i + 1
yield func
g = foo()

lst = []
for i in g:
lst.append(i())
print(lst)
結果:[1,2,3]
1四、lambda函數舉例五:
g = [lambda x:x*i for i in range(3)]
for j in [2,10]:
g1 = (em(3) for em in g)
print([e+j for e in g1])
結果:[16, 16, 16]
1五、lambda函數舉例六:
lst = []    #[func,func,func]
for i in range(3):
def func(x):
return x * i #3*2
lst.append(func)

for j in [2,10]:
def g1(): #循環產生兩個生成器、第二個生成器10覆蓋第一個的2
for em in lst:
yield em(3) #func(3)

new_lst = []
for e in g1():
new_lst.append(e + j) #g1是六、e是六、j是10
print(new_lst)
# 結果:[16, 16, 16]
1六、模擬高階函數filter過濾:
filter函數是把列表中的值全部的都篩選一遍最後在獲得一個值(列表)
lst = [1,2,3,4,54,65,7,8]
def foo(x): #規則函數
return x > 4 #判斷的是True和False

def f(func,iter): #filter
lst = [] #[54,65,7,8]
for i in iter:
if func(i):
lst.append(i)
return lst
print(f(foo,lst))
# 結果:[54, 65, 7, 8]
1七、高階函數filter:
lst = [1,2,3,4,54,65,7,8]
print(list(filter(lambda x:x > 4,lst)))
1八、#過濾掉年齡大於等於17的
lst = [{'id':1,'name':'alex','age':18},
{'id':1,'name':'wusir','age':17},
{'id':1,'name':'taibai','age':16},]
print(list(filter(lambda x:x["age"] >= 17,lst)))
結果:[{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}]
1九、過濾掉名字長度大於等於5的(過濾出是拿到、過濾掉是不要)
lst = [{'id':1,'name':'alex','age':18},
{'id':1,'name':'wusir','age':17},
{'id':1,'name':'taibai','age':16},]
print(list(filter(lambda x:len(x["name"]) >= 5,lst)))
# 結果:[{'id': 1, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'taibai', 'age': 16}]
20、高階函數map映射--將可迭代對象中每一個元素執行函數功能:
map函數是裝一個列表依次處理獲得的仍是一個列表,跟原先的列表順序同樣、只不過每一個元素被處理了
轉成字符串:
lst = [1,2,3,4,5,6,8,9]
print(list(map(str,lst)))
# 結果:['1', '2', '3', '4', '5', '6', '8', '9']
合併求列表和:
lst1 = [1,2,3]
lst2 = [3,2,1]
print(list(map(lambda x,y:x + y,lst1,lst2)))
結果:[4, 4, 4]
2一、sorted排序函數:
lst = [1,2,3,4,65,7]
print(sorted(lst)) #新建列表
結果:[1, 2, 3, 4, 7, 65]

lst.sort()
print(lst) #原地修改
結果:[1, 2, 3, 4, 7, 65]
print(sorted("alex,mdsb"))              #升序
結果:[',', 'a', 'b', 'd', 'e', 'l', 'm', 's', 'x']
print(sorted("alex,mdsb",reverse=True)) #降序
結果:[',', 'a', 'b', 'd', 'e', 'l', 'm', 's', 'x']
排鍵:
dic = {1:"a",3:"c",2:"b"}
print(sorted(dic))
結果:[1, 2, 3]
四大名著排序:
lst = ['天龍八部','西遊記','紅樓夢','三國演義']
print(sorted(lst,key = len)) #key = 排序規則
結果:['西遊記', '紅樓夢', '天龍八部', '三國演義']
lst = [{'id':1,'name':'alex','age':18},
{'id':2,'name':'wusir','age':17},
{'id':3,'name':'taibai','age':16},]
print(sorted(lst,key=lambda x:x['age'],reverse=True))
# 結果:[{'id': 1, 'name': 'alex', 'age': 18}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 3, 'name': 'taibai', 'age': 16}]
2二、max最大值:
print(max([1,2,3,4,5,6,-9,10,-22],key=abs))
結果:-22
2三、min最小值:
print(min([1,2,3,4,5,6,-9,10,-22],key=abs))
結果:1
2四、reduce累計算:
reduce函數是能夠把完整的序列合併到一起最終獲得一個值
累乘:
from functools import reduce
lst = [1,2,3,4,5]
print(reduce(lambda x,y:x*y,lst))
結果:120
2五、zip拉鍊:
lst1 = [1,2,3,4,5]
lst2 = [5,4,3,2,1]
print(list(zip(lst1,lst2)))
結果:[(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]
2六、print加參數分隔符
print("alex","wusir","太亮",sep="|")
結果:alex|wusir|太亮
print("alex","wusir","太亮",sep="|",end="")
print("meet")
結果:alex|wusir|太亮meet
做業題:
三次登錄鎖定:
"""
四.用代碼實現三次用戶登陸及鎖定(選作題,這是一個單獨的程序)
項目分析:
一.首先程序啓動,顯示下面內容供用戶選擇:
1.註冊
2.登陸
a.用戶選擇登陸的時候,首先判斷用戶名在userinfo.txt表中存在不在,存在就不能進行註冊
b.當註冊的用戶名不存在的時候將用戶名和密碼寫入到userinfo.txt文件中
c.用戶選擇登陸的時候,判斷用戶輸入的帳號和密碼是否userinfo.txt存儲的一致
d.用戶名和密碼一致就終止循環,並提示用戶登陸成功!
e.用戶名和密碼不一致,只有三次登陸機會,三次事後提示用戶名被鎖定,請聯繫管理員!並終止循環
f.當用戶名錯誤三次,再次運行程序.登陸鎖定的帳號繼續提示用戶名被鎖定,請聯繫管理員!
"""
# 結束標識
quite_flag = False # ------------------------------二、

# 錯誤登陸次數 #------------------------------------三、
login_fail = 0

# 登陸功能
def login(): # -----------------------------五、
"""
登陸
:return:
"""
while True:
global login_flag # 定義全局登陸狀態
global quite_flag # 定義全局結束標識
global login_fail # 定義全局登陸次數
user_name = input ( "請輸入登陸用戶名:" )
password = input ( "請輸入密碼:" )
if user_name in userinfo_dic:
login_flag = True if password == userinfo_dic[user_name] else False
if userinfo_dic[user_name + "locked"] == "True":
login_flag = False
print ( "用戶名被鎖定,請聯繫管理員!" )
break
if login_flag:
print ( "登錄成功!" )
quite_flag = True
break
else:
login_fail += 1
if login_fail == 3:
modif_userinfo(user_name,userinfo_dic[user_name],str(True))
quite_flag = True
print("用戶名被鎖定,請聯繫管理員!")
break
else:
print("用戶帳號或密碼錯誤,請從新輸入")
else:
print("用戶名不存在!請從新輸入!")



# 註冊功能
def register():
"""
註冊
:return:
"""
while True:
user_name = input ( "請輸入用戶名(不能有特殊字符):" )
password = input ( "請輸入密碼長度要在6~14個字符之間:" )
if user_name not in userinfo_dic:
if user_name.isalnum () and 5 < len ( password ) < 15:
write_userinfo ( user_name, password )
print ( "註冊成功!" )
global login_fail # 聲明全局錯誤登陸次數
login_fail = 0
global login_flag # 聲明全局登陸狀態
login_flag = True #改爲登陸狀態True
break #改爲break至關於註冊完畢了
else:
print ( "輸入錯誤,請從新輸入" )
else:
print ( "用戶名已存在!請從新輸入!" )


def quite():
"""
退出
:return:
"""
global quite_flag
quite_flag = True


# 定義用戶讀取文件信息功能
def read_userinfo(path_add: str):
"""
讀取用戶信息
:return:
"""
with open ( path_add, "a+", encoding="utf-8" ) as f:
global userinfo_dic
f.seek ( 0 )
for i in f:
if i != "\n" and i != "" and i is not None:
userinfo_dic[i.split ( ":" )[0].strip ()] = i.split ( ":" )[1].strip ()
userinfo_dic[i.split ( ":" )[0].strip () + "locked"] = i.split ( ":" )[2].strip ()


# 定義用戶寫入文件信息功能
def write_userinfo(user_name: str, password: str):
"""
寫入用戶信息
:param user_name:
:param password:
:return:
"""
with open ( path_add, "a", encoding="utf-8" ) as f1: #a模式、防止文件不存在時報錯
f1.write ( f"\n{user_name}:{password}:False" ) #第一次註冊往字典裏面添加狀態沒有被鎖定
f1.flush ()
global login_fail # 定義全局錯誤登陸次數
userinfo_dic[user_name] = password # 字典是可變數據類型、在局部使用全局進行修改不用使用global、往字典裏面增長鍵值對
userinfo_dic[user_name + "locked"] = str ( False ) # 往用戶信息字典裏面創建用戶鎖定狀態


# 定義用戶鎖定信息功能
def modif_userinfo(user_name: str, password: str, locked: str):
"""
鎖定用戶信息修改
:param user_name:
:param password:
:param locked:
:return:
"""
with open ( path_add, "r", encoding="utf-8" ) as f4, \
open ( path_add.replace ( ".txt", "1.txt" ), "w", encoding="utf-8" ) as f5:
for i in f4:
if i != "\n" and i.split ( ":" )[0].strip () == user_name:
i = f"{user_name}:{password}:{locked}\n"
f5.write ( i )
f5.flush ()
global userinfo_dic
userinfo_dic[user_name] = password
userinfo_dic[user_name + "locked"] = locked
import os
import time
os.rename ( path_add, path_add.replace ( ".txt", str ( time.time () ) + ".bak" ) )
os.rename ( path_add.replace ( ".txt", "1.txt" ), path_add )
global login_fail # 定義全局登陸次數
login_fail = 0


# 組成字典容器
choose_dic = {"1": register,
"2": login,
}

# 新建已註冊的用戶帳戶和密碼字典形式:
userinfo_dic = dict ()

# 定義文件地址信息存儲位置變量
path_add = "userinfo_single.txt"

# 讀取一下已經註冊的用戶和密碼
read_userinfo ( path_add )

# 登錄信息提示:#-----------------------------------一、
print ( """1.註冊
2.登陸""" )

# 主程序 #---------------------------------------四、
while not quite_flag:
choose = input ( "請選擇您要進行的操做對應的序號:" )
choose_dic[choose] () if choose in choose_dic else print ( "輸入錯誤,請從新輸入!" )
else:
print ( "結束" )
# 一、用列表推導式作下列小題lst = ["alex","wusir","太白","寶元"]# 過濾掉長度小於3的字符串列表,並將剩下的轉換成大寫字母print([i.upper() for i in lst if len(i) > 3])# 二、求[{x:y}]其中x是0-5之間的偶數組成的元組的,y是0-5之間的奇數組成的元組print([{tuple([i for i in range(0,6,2)]):tuple([i for i in range(1,6,2)])}])# 三、求3,6,9 組成的列表結果: M = [[1,2,3],[4,5,6],[7,8,9]]print([[i for i in range(1,4)],[i for i in range(4,7)],[i for i in range(7,10)]])# print([i-2,i-1,i] for i in [3,6,9])?????????????????????????這道題我不會作太難了# 四、求出50之內能被3整除的數的平方,並放入到一個列表中。print([i**2 for i in range(51) if i // 3])# 五、構建一個列表:['python1期', 'python2期', 'python3期', 'python4期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']print(["python%s期" %i for i in range(1,11)])# 六、構建一個列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]# 七、構建一個列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]print([i for i in range(20) if i % 2 == 0])# 八、有一個列表l1 = ['alex', 'WuSir', '老男孩', '太白']將其構形成這種列表# ['alex0', 'WuSir1', '老男孩2', '太白3']print(['%s%s' %(l1,i) for i,l1 in enumerate(l1)])# for循環形式:# l1 = ['alex','Wusir','老男孩','太白']# for i,em in enumerate(l1):#     print(em + str(i))# 九、有如下數據類型:x = {'name':'alex','Values':[{'timestamp':1517991992.94,'values':100,},{'timestamp': 1517992000.94,'values': 200,},{'timestamp': 1517992014.94,'values': 300,},{'timestamp': 1517992744.94,'values': 350},{'timestamp': 1517992800.94,'values': 280}],}# 將上面的數據經過列表推導式轉換成下面的類型:[[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]print([[i["timestamp"],i["values"]] for i in x["Values"]])# 十、構建一個列表,列表裏面是三種不一樣尺寸的T恤衫,每一個尺寸都有兩個顏色(列表裏面的元素爲元組類型)。# colors = ['black', 'white']# sizes = ['S', 'M', 'L']print(list(zip(colors,sizes)))# 十一、構建一個列表,列表裏面的元素是撲克牌除去大小王之後,全部的牌類(列表裏面的元素爲元組類型)。# l1 = [('A','spades'),('A','diamonds'), ('A','clubs'), ('A','hearts')......('K','spades'),('K','diamonds'), ('K','clubs'), ('K','hearts') ]# 十二、看代碼求結果(面試題):# v = [i % 2 for i in range(10)]# print(v)# 結果:[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]# v = (i % 2 for i in range(10))# print(v)# 結果:<generator object <genexpr> at 0x0000000002152D00> #生成器內存地址
相關文章
相關標籤/搜索