三元表達式、列表推導式、生成器表達式、遞歸、匿名函數、內置函數

三元表達式html

# what:就是簡寫if...else...結構,且都只有一條語句
# 語法:結果1 if 條件 else 結果2
# 注意:結果1|2不必定要與條件有必然關係,條件只是選擇結果1或結果2的判斷依據

# 案例:得到兩個數中的大值 | 小者
n1 = int(input('n1: '))
n2 = int(input('n2: '))
res = n1 if n1 > n2 else n2
print(res)
res = n2 if n1 > n2 else n1
print(res)

列表字典推導式python

# 列表推導式
# 語法:[結果 for 結果 in 可for循環操做的對象]
# 案例:[v for v in 'abc'] => ['a', 'b', 'c']

# 產生1~10之間的偶數list => [2, 4, 6, 8, 10]
ls = [i for i in range(2, 11, 2)]  # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(ls)

# 1~5之間的數用奇數偶數形參list => ['奇數', '偶數', '奇數', '偶數','奇數']
ls = ['奇數' if i % 2 != 0 else '偶數' for i in range(1, 6)]
print(ls)

ls = ('奇數' if i % 2 != 0 else '偶數' for i in range(1, 6))
print(tuple(ls))


#字典推導式
# 語法:{k: v for k, v in 可for循環操做的對象(每一次循環的結果能夠被解壓爲兩個值)}
# 案例:
# 原數據: [('a', 1), ('b', 2)] => {'a': 1, 'b': 2}
source = [('a', 1), ('b', 2)]
dic = {k: v for k, v in source}
print(dic)

dic = {i: 0 for i in 'abc'}
print(dic)
#print({}.fromkeys('abc', 0))

迭代器面試

# 尋求一種不依賴索引,且能夠循環取值的方式
dic = {'a': 1, 'b': 2, 'c': 3}
print(dic) # {'a': 1, 'b': 2, 'c': 3}

# 經過__iter__()方法獲取dic的一個不用依賴索引的取值容器
box = dic.__iter__()
print(box) #<dict_keyiterator object at 0x0000000001D9D4A8>
print(box.__next__()) #a

box3 = 'abc'.__iter__()
print(box3) # <str_iterator object at 0x0000000001E7CBA8>
print(box3.__next__()) # a

box4 = {'a', 'b', 'c'}.__iter__()
print(box4)  # <set_iterator object at 0x0000000001EBA708>
print(box4.__next__()) # a
print(box4.__next__()) # b

'''
1.txt內容:
11111111
22222222
33333333
44444444
'''
with open('1.txt', 'r', encoding='utf-8') as r:
    print(r)  # <_io.TextIOWrapper name='1.txt' mode='r' encoding='utf-8'>
    print(r.__next__())  # 11111111
    print(r.__next__())  #  22222222
# 可迭代對象
# 有__iter__()方法的對象都稱之爲 可迭代對象

# 可迭代對象:能夠被轉化爲不依賴索引取值的容器,這樣的對象就叫作可迭代對象
#       -- 對象.__iter__() 來生成不依賴索引取值的容器
#       -- 結論:有__iter__()方法的對象都稱之爲 可迭代對象

# 可迭代對象.__iter__() => 和該對象有關係的迭代器對象 dict_keyiterator object
box = dic.__iter__()  

# 可迭代對象有哪些:str | list | tuple | set | dict | range() | enumerate() | file | 生成器對象
# 迭代器對象:
# 有__next__()且能夠經過__next__()進行取值的容器

# 迭代器對象:能夠經過__next__()的方式進行取值的容器,且取一個少一個
#       -- 結論:有__next__()且能夠經過__next__()進行取值的容器
#       -- 注意:迭代器對象自身也擁有__iter__(), 經過該方法返回的是迭代器對象自身

res = box.__next__()  # 從迭代器對象(容器)取出值,取一個少一個
box = box.__iter__()  # 迭代器對象.__iter__()獲得迭代器對象自己

# 迭代器對象有哪些:enumerate() | file | 生成器對象
# 迭代器(for循環):就是用來從可迭代對象中進行取值的循環方法 | 語法:for 變量 in 對象:
#       -- 1.經過對象.__iter__()獲取其對應的迭代器對象
#           -- for能夠操做迭代器對象及可迭代對象,統一寫法,因此迭代器和可迭代對象都有__iter__()
#       -- 2.在內部經過迭代器對象的__next__()進行取值,將值賦值給 語法中的變量,取一個少一個
#       -- 3.當迭代器對象取完了,在內部自動捕獲異常,並結束循環取值

dic1 = {'a': 1, 'b': 2, 'c': 3}  # dic是可迭代對象
dic1_box = dic1.__iter__()  # 經過__iter__()獲得的是迭代器對象
# print(len(dic1_box))  # 迭代器對象沒有len()方法
while True:
    try:
        print(dic1_box.__next__())
    except StopIteration:   #捕捉報錯,並退出
        print('取完了')
        break

for v in dic1:
    print(v)

生成器api

# 生成器:自定義的迭代器對象
def fn():
    print(1)
    yield 666
    print(2)
    yield 888
    print(3)

obj = fn()  # generator object => [666, 888]
# print(obj) # <generator object fn at 0x0000000001E24C50>
# 去生成器中執行代碼,拿到遇到的第一個yield後面的值,並中止運行
print(obj.__next__()) # 1 666
# 再接着上一個yield,再進行往下執行代碼,再拿到下一個個yield後面的值,並中止運行
print(obj.__next__()) # 2 888
# 重複上面的過程,若是沒有遇到yield,就報錯
print(obj.__next__()) # StopIteration

# 舉例
#一、示例:生一筐雞蛋變成給你一隻老母雞,用的時候就下蛋,這也是生成器的特性
>>> chicken=('雞蛋%s' %i for i in range(5))
>>> chicken
<generator object <genexpr> at 0x10143f200>
>>> next(chicken)
'雞蛋0'
>>> list(chicken) #因chicken可迭代,於是能夠轉成列表
['雞蛋1', '雞蛋2', '雞蛋3', '雞蛋4',]

#二、優勢:省內存,一次只產生一個值在內存中

# 將傳入的值擴大兩倍返回
def fn1(a, b, c):
    yield a * 2
    yield b * 2
    yield c * 2

# 解決方案
def fn1(*args):
    i = 0
    while i < len(args):
        yield args[i] * 2
        i += 1

for v in fn1(10, 20, 30, 40, 50):
    print(v)

# 依次獲取階乘 1! 2! 3! ...
def fn2():
    total = 1
    count = 1
    while True:
        total *= count
        yield total
        count += 1

obj = fn2()
print(obj.__next__())  # 1!=1
print(obj.__next__()) # 2!=2
print(obj.__next__()) # 3!=6
print(obj.__next__()) # 4!=24

了了解app

def fn3():
    msg = yield 1
    print(msg)
    yield 2
obj3 = fn3()
print(obj3.__next__())
# 1.send會爲當前中止的yield傳入參數,內部能夠經過yield來接收傳入的參數
# 2.send自身也會調用__next__()去獲取下一個yield的結果
result = obj3.send('ooo')
print(result)
舉例:
def fn4(peoples):
    count = 0
    print('%s在面試' % peoples[count])
    while count < len(peoples):
        name = yield peoples[count]
        count += 1
        print(name + "叫來%s來面試" % peoples[count])

peoples = ['張三', '李四', '王五']
obj4 = fn4(peoples)
name = obj4.send(None)  # 第一次沒有yield接收值,因此只能調__next__(),或是send(None)
print(name + '面試完畢')
while True:
    try:
        name = obj4.send(name)
        print(name + '面試完畢')
    except Exception:
        print('全部人面試完畢')
        break

枚舉對象ide

# 枚舉對象:爲迭代器對象產生迭代索引

ls = [3, 1, 2, 5, 4]
list(enumerate(ls))  # => [(0, 3), (1, 1), (2, 2), (3, 5), (4, 4)]

dic = {'a': 100, 'b': 200}
print(list(enumerate(dic)))  # => [(0, 'a'), (1, 'b')]

遞歸函數

# 遞歸:函數直接或間接調用本身
# 回溯:找尋答案的過程
# 遞推:經過最終的值反向一步步推出最初須要的結果

# 前提:
# 1.遞歸條件是有規律的
# 2.遞歸必須有出口
import sys
print(sys.getrecursionlimit()) # 最大遞歸層 1000
sys.setrecursionlimit(100) #能夠修改最大遞歸次數
# 舉例
# 拿遞歸求得年紀
def get_age(num):
    if num == 1:
        return 58
    age = get_age(num - 1) - 2
    return age
age = get_age(10)
print(age)

# 傳入一個num,求得該num的階乘
# 5! = 5 * 4 * 3 * 2 * 1 = 5 * 4!
# 4! = 4 * 3 * 2 * 1 = 4 * 3!
# 3! = 3 * 2 * 1 = 3 * 2!
# 2! = 2 * 1 = 2 * 1!
# 1! = 1
def get_total(num):
    if num == 1 or num == 0:
        return 1
    total = num * get_total(num - 1)  # 3 * 2! => 2 * 1!1 => 1 => 2 * 1
    return total
print(get_total(3))

匿名函數spa

# 匿名函數:沒有名字的函數
# 1.用lambda聲明匿名函數
# 2.沒有函數名,lambda與:之間必定是參數列表,參數列表省略(),且支持全部參數語法
# 3.匿名函數沒有函數體,只有返回值,全部省略了return,且返回值只能有一個
#       -- (不能將多個返回值自動格式化爲元組)
# lambda 參數1, ..., 參數n: 一個返回值
# 應用場景
# 1.用一個變量接收,該變量就充當與函數的名字 - 不常見
func = lambda x, y: (x + y, x - y)
print(func(10, 20))

# 2.結合內置函數來使用
y=(max([1, 2, 6, 5, 3], key=lambda x: x))
print(y) # 6
dic = {
    'Bob': (1, 88888),
    'Ben': (2, 300000),
    'Tom': (3, 99999)
}
s = min(dic, key=lambda k: dic[k][1])  # 按薪資求最小值
print(s) #Bob

內置函數code

官方3.7.3列出內置函數:https://docs.python.org/zh-cn/3/library/functions.htmlhtm

# 已見過的
# 1.類型轉換:int() tuple()
# 2.常規使用:print() input() len() next() iter() open() range() enumerate() id()
# 3.進制轉換:bin() oct() hex() 將10進制轉換爲2 | 8 | 16進制
print(bin(10))  # 0b1010
print(oct(10))  # 0o12
print(hex(10))  # 0xa

# 3.運算:abs()
print(abs(-1))  # 絕對值
print(chr(9326))  # 將ASCII轉換爲字符
print(ord(''))  # 逆運算
print(pow(2, 3))  # 2的3次方
print(pow(2, 3, 3))  # 2的3次方對3求餘
print(sum([1, 2, 3]))  # 求和

# 4.反射:getattr() delattr() hasattr() setattr()

# 5.面向對象的相關方法:super() staticmethod() classmethod()
def fn():pass
print(callable(fn))  # 對象能不能被調用

# 6.原義字符串
print('a\nb')
s = ascii('a\nb')
print(s)
s = repr('a\nb')
print(s)
print(r'a\nb')

print(all([1, 0, 0]))
print(any([0, 0, 1]))

# compile() exec() eval()
# max的工做原理
# 1.max要去遍歷全部求大值的數據,這些一一被遍歷出來的數要被依次傳入key=fn的fn中
#       -- fn必須有參數,且只有一個參數,就是當前被遍歷出來的被比較的數據
# 2.max再根據fn的返回值決定比較大小的依據
dic = {
    'owen': (1, 88888),
    'egon': (2, 300000),
    'liuXX': (3, 99999)
}
def fn2(k):
    # return k  # 求名字最大
    # return dic[k][0]  # 求工號最大
    return dic[k][1]  # 求薪資最大
max_p = max(dic, key=fn2)
print(max_p) # egon

# min函數的工做原理
# 1.min要去遍歷全部求小值的數據,這些一一被遍歷出來的數要被依次傳入key=fn的fn中
#       -- fn必須有參數,且只有一個參數,就是當前被遍歷出來的被比較的數據
# 2.min再根據fn的返回值決定比較大小的依據

dic = {
    'owen': (1, 88888),
    'egon': (2, 300000),
    'liuXX': (3, 99999)
}
res = min(dic, key=lambda x: dic[x][1])
print(res)

# 排序:sorted
dic = {
    'owen': (1, 88888),
    'egon': (2, 300000),
    'liuXX': (3, 99999)
}

# 總結:排序的可迭代對象,排序的規則,是否反轉
res = sorted(dic, key=lambda k: dic[k][1], reverse=True)  # 按薪資排序的人名list
for k in res:
    print(k, dic[k][1])

# map:映射 - 格式化每一次的遍歷結果
names = ['Owen', 'Egon', 'Liuxx']
def fn(x):
    # print(x)
    # 將全部名字全小寫
    return x.lower()

res = map(fn, names)
print(list(res))

dic1 = {
    'owen': 88888,
    'egon': 300000,
    'liuXX': 99999
}
def fn1(x):
    dic1[x] += 1
    return 10000
# 總結:遍歷第二個參數(可迭代對象),將遍歷的結果丟給第一個函數,
# 函數有一個參數,就是一一遍歷的值
# map的做用(返回值):在當前數據基礎上改變值(能夠任意修改)
res = map(fn1, dic1)
print(list(res))
print(dic1)

# 合併:reduce
from functools import reduce
# 求[1, 3, 4, 2, 10]全部元素的總和
res = reduce(lambda x, y: x + y, [1, 3, 4, 2, 10])
print(res)
模塊舉例

練習:

1、文件內容以下,標題爲:姓名,性別,年紀,薪資

egon male 18 3000
alex male 38 30000
wupeiqi female 28 20000
yuanhao female 28 10000

要求:
從文件中取出每一條記錄放入列表中,
列表的每一個元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式

2 根據1獲得的列表,取出薪資最高的人的信息
3 根據1獲得的列表,取出最年輕的人的信息
4 根據1獲得的列表,將每一個人的信息中的名字映射成首字母大寫的形式
5 根據1獲得的列表,過濾掉名字以a開頭的人的信息
6 使用遞歸打印斐波那契數列(前兩個數的和獲得第三個數,如:0 1 1 2 3 4 7...)
7 一個嵌套不少層的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用遞歸取出全部的值
#1
with open('db.txt') as f:
    items=(line.split() for line in f)
    info=[{'name':name,'sex':sex,'age':age,'salary':salary} \
          for name,sex,age,salary in items]

print(info)
#2
print(max(info,key=lambda dic:dic['salary']))

#3
print(min(info,key=lambda dic:dic['age']))

# 4
info_new=map(lambda item:{'name':item['name'].capitalize(),
                          'sex':item['sex'],
                          'age':item['age'],
                          'salary':item['salary']},info)

print(list(info_new))

#5
g=filter(lambda item:item['name'].startswith('a'),info)
print(list(g))

#6
#非遞歸
def fib(n):
    a,b=0,1
    while a < n:
        print(a,end=' ')
        a,b=b,a+b
    print()

fib(10)
#遞歸
def fib(a,b,stop):
    if  a > stop:
        return
    print(a,end=' ')
    fib(b,a+b,stop)

fib(0,1,10)


#7
l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]]

def get(seq):
    for item in seq:
        if type(item) is list:
            get(item)
        else:
            print(item)
get(l)
練習
相關文章
相關標籤/搜索