1. 程式人生 > >(列表推導式,生成器表達式,內置函數)

(列表推導式,生成器表達式,內置函數)

全局局部變量 通過 實例 app compile 根據 重要 字符編碼 初始

一,列表生成式

示例一:

生成1~100的列表

生成1~100的列表

1 2 3 4 5 li = [] for i in range(1,101): li.append(i) print(li)

執行輸出:

[1,2,3...]

生成python1期~11期
li = []
for i in range(1,12):
li.append(‘python{}期‘.format(i))
print(li)

執行輸出:

[‘python1期‘, ‘python2期‘, ‘python3期‘...]

第二種寫法

1 2 3 4 li
= [] for i in range(1,12): li.append(‘python%s‘ % i) print(li)

執行輸出,效果同上

推導式

上面的代碼,一行搞定,用列表推到式就可以了。

用列表推到式能構建任何列表,用戶別的可以構建,比如for循環

特點:

1.一行簡單,感覺高端,但是不易排錯

使用debug模式,每發一次查看每一個值

第一個例子:

li = [i for i in range(1,101)]
print(li)

 第二個例子:

li = [‘python%s期‘ %i for i in range(1,12)]
print(li)

  

 循環模式

#循環模式
[經過加工的i for i in 可叠代對象]

 比如python1期~python12期,是加工的也可以不加工,比如1~100

 實例一:

li = [ i ** 2 for i in range(1,11) ]
print(li)

 

篩選模式

1 [經過加工的i for i in 可叠代對象 if 條件 篩選] 

30以內所有能被3整除的數

l3 = [i for i in range(1,31) if i % 3 == 0]
print(l3)

 執行輸出:

[3, 6, 9, 12, 15, 18, 21, 24, 27, 30]

 

找到嵌套列表中名字含有兩個‘e’的所有名字

names = [[‘Tom‘, ‘Billy‘, ‘Jefferson‘, ‘Andrew‘, ‘Wesley‘, ‘Steven‘, ‘Joe‘],
[‘Alice‘, ‘Jill‘, ‘Ana‘, ‘Wendy‘, ‘Jennifer‘, ‘Sherry‘, ‘Eva‘]]
l4 = [name for i in names for name in i if name.count(‘e‘) == 2]
print(l4)

列表推導式,最多不超過3個for循環
判斷只能用一個
常用的是列表推導式

常用的列表推導式

字典推導式
將一個字典的key和value對調
mcase = {‘a‘:10,‘b‘:34}
mcase_frequency = {mcase[k]:k for k in mcase}
print(mcase_frequency)

  執行輸出:

{10: ‘a‘, 34: ‘b‘}

如果key和value 是一樣的,不適合上面的代碼。

計算列表中的每個值的平方,自帶去重功能。

squared = {x ** 2 for x in [1,-1,2]}
print(squared)

  執行輸出:
{1, 4}

二,生成器表達式

l_obj = (‘python%s期‘ % i for i in range(1,12))
print(l_obj)
執行輸出
<generator object <genexpr> at 0x00000190FEF4C3B8>
結果是一個生成器對象
如何取值呢?
使用__next__方法

1 2 3 4 5 l_obj = (‘python%s期‘ % i for i in range(1,12)) #print(l_obj) print(l_obj.__next__()) print(l_obj.__next__()) print(l_obj.__next__())

執行輸出:

python1期
python2期
python3期

列表推導式:一目了然,占內存
生成器表達式: 不便看出,節省內存。

 三,內置函數

技術分享圖片

什麽是內置函數?就是python給你提供的,拿來直接用的函數,比如:print,input 等等。截至到python版本3.6.2,現在python一共為我們提供了68個內置函數。它們就是python提供給你直接可以拿來使用的所有函數。

技術分享圖片

??? 表示很重要

? 表示一般

作用域相關

locals:函數會以字典的類型返回當前位置的全局局部變量。

globals:函數以字典的類型返回全部全局變量。

其他相關

字符串類型代碼的執行 evel,exec,compile

???eval:執行字符串類型的代碼,並返回最終結果。

1 print(eval(‘3+4‘))

執行輸出: 7

1 2 ret = eval(‘{"name":"老司機"}‘) print(ret)

執行輸出: {‘name‘: ‘老司機‘}

eval 的作用相當於撥開字符串2邊的引號,執行裏面的代碼

???exec:執行字符串類型的代碼,流程語句

1 print(exec(‘3+4‘))

執行輸出:None

1 2 3 4 5 6 ret1 = ‘‘‘ li = [1,2,3] for i in li: print(i) ‘‘‘ print(exec(ret1))

執行輸出:

1
2
3
None

eval和exec 功能是類似的
區別:
1.eval有返回值,exec沒有沒有值
2.exec適用於有流程控制的,比如for循環。eval只能做一些簡單的。

compile:將字符串類型的代碼編譯。代碼對象能夠通過exec語句來執行或者eval()進行求值。

code1 = ‘for i in range(0,3):print(i)‘
compile1 = compile(code1,‘‘,‘exec‘)
exec(compile1)

  

執行輸出:

0
1
2

compile這個函數很少用,未來幾年都不會用得到

輸入輸出相關 input,print

???input:函數接受一個標準輸入數據,返回為 string 類型。
???print:打印輸出。

print(333,end=‘**‘)
print(666,)

  

執行輸出:

333**666

默認是用空格拼接

sep 將每一個字符串拼接起來,這裏指定使用|

1 print(11, 22, 33, sep = ‘|‘)

執行輸出:

11|22|33

寫入文件

1 2 with open(‘log.txt‘,encoding=‘utf-8‘,mode=‘w‘) as f1: print(‘5555‘,file=f1)

執行程序,查看log.txt文件內容為: 555


內存相關 hash id
???id:用於獲取對象的內存地址。

a = 123
print(id(a))

  執行輸出:

1640522336

???hash:獲取一個對象(可哈希對象:int,str,Bool,tuple)的哈希值。

1 2 print(hash(123)) #數字不變 print(hash(‘123‘))

執行輸出:

123
4876937547014958447

true和False 的哈希值對應1和0

1 2 print(hash(True)) print(hash(False))

執行輸出:

1
0

模塊相關__import__ 
__import__:函數用於動態加載類和函數 。

?help:函數用於查看函數或模塊用途的詳細說明。

調用相關
???callable:函數用於檢查一個對象是否是可調用的。如果返回True,object仍然可能調用失敗;但如果返回False,調用對象ojbect絕對不會成功。
判斷對象是否可調用的,就判斷它是不是一個函數名
函數名返回True,其他,返回False

def func1():
    print(555)
a = 3
f = func1
print(callable(f))
print(callable(a))

執行輸出:

True
False

callable其實就是判斷一個對象是否是函數,是就返回True,其他類型直接返回False

查看內置屬性

???dir:函數不帶參數時,返回當前範圍內的變量、方法和定義的類型列表;帶參數時,返回參數的屬性、方法列表。如果參數包含方法__dir__(),該方法將被調用。如果參數不包含__dir__(),該方法將最大限度地收集參數信息。

print(dir(list))

 

執行輸出:

[‘__add__‘, ‘__class__‘, ‘__contains__‘...]

叠代器生成器相關
???range:函數可創建一個整數對象,一般用在 for 循環中。
?next:內部實際使用了__next__方法,返回叠代器的下一個項目。

#首先獲得Iterator對象:
it = iter([1,2,3,4,5])
#循環:
while True:
    try:
        #獲得下一個值:
        x = next(it)  #next內部封裝了__next__方法,都是求下一個值
        print(x)
    except StopIteration:
        #遇到StopIteration就退出循環
        break

 

執行輸出:

1
2
3
4
5

?iter:函數用來生成叠代器(講一個可叠代對象,生成叠代器)。

from collections import Iterable
from collections import Iterable
l = [1,2,3]
print(isinstance(l,Iterable)) #判斷是否可叠代
print(isinstance(l,Iterable)) #判斷是否為可叠代器

  數字相關
  
數據類型:
???bool :用於將給定參數轉換為布爾類型,如果沒有參數,返回 False。
???int:函數用於將一個字符串或數字轉換為整型。經常用

1 2 3 4 print(int()) print(int(‘12‘)) print(int(3.6)) print(int(‘0100‘,base=2)) # 將2進制的 0100 轉化成十進制。結果為 4

print(int())
print(int(‘12‘))
print(int(3.6))
print(int(‘0100‘,base=2)) #將2進制的 0100轉化成十進制。結果為 4

float:函數用於將整數和字符串轉換成浮點數。
complex:函數用於創建一個值為 real + imag * j 的復數或者轉化一個字符串或數為復數。如果第一個參數為字符串,則不需要指定第二個參數

將數字轉換為浮點型,默認保留小數點1位

print(type(3.14))
print(float(3))

 

執行輸出:

<class ‘float‘>
3.0

進制轉換:
?bin:將十進制轉換成二進制並返回。
?oct:將十進制轉化成八進制字符串並返回。
?hex:將十進制轉化成十六進制字符串並返回。

print(bin(5))
print(oct(7))
print(hex(10))  #10 用a表示

執行輸出:

0b101
0o7
0xa

數學運算:
?abs:函數返回數字的絕對值。
?divmod:計算除數與被除數的結果,返回一個包含商和余數的元組(a // b, a % b)。
round:保留浮點數的小數位數,默認保留整數。
pow:求x**y次冪。(三個參數為x**y的結果對z取余)

print(abs(-20)) #絕對值

  執行輸出: 20

print(divmod(10,2))

  執行輸出:

(5, 0)

divmod 在分頁功能中,會用用到此函數

print(round(3.1415))

  執行輸出:3

print(pow(2,3,5)) 

 

執行輸出: 2

解釋:這裏為3個參數,2的3次方,結果為8。用8和5做除法,取余為3,最終輸出3

 

???sum:對可叠代對象進行求和計算(可設置初始值)。
???min:返回可叠代對象的最小值(可加key,key為函數名,通過函數的規則,返回最小值)。
???max:返回可叠代對象的最大值(可加key,key為函數名,通過函數的規則,返回最大值)。

1 print(sum([1,2,3,4]))

執行輸出: 10

sum最多只有2個參數

1 print(max([1,2,3,4]))

執行輸出: 4

ret = max([1,2,-5],key=abs)
print(ret)

 

執行輸出: -5

key表示定義規則

和數據結構相關
列表和元祖
???list:將一個可叠代對象轉化成列表(如果是字典,默認將key作為列表的元素)。
???tuple:將一個可叠代對象轉化成元祖(如果是字典,默認將key作為元祖的元素)。

相關內置函數 

 ???reversed:將一個序列翻轉,並返回此翻轉序列的叠代器。

slice:構造一個切片對象,用於列表的切片。

1 2 3 ite = reversed([‘a‘,2,3,‘c‘,4,2]) for i in ite: print(i)

執行輸出:

2
4
c
3
2
a

li = [‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘,‘g‘]
sli_obj = slice(3)
print(li[sli_obj])

執行輸出: 

[‘a‘, ‘b‘, ‘c‘]

如果有10個列表,統一切前3個,sli_obj可能有點用

slice幾乎用不到
slice可以定義一個切片規則

字符串相關
???str:將數據轉化成字符串。
???format:用於格式化輸出

字符串可以提供的參數,指定對齊方式,<是左對齊, >是右對齊,^是居中對齊

1 2 3 print(format(‘test‘, ‘<20‘)) print(format(‘test‘, ‘>20‘)) print(format(‘test‘, ‘^20‘))

執行輸出:

1 2 3 test test test

???bytes:用於不同編碼之間的轉化。

編碼轉換,將unicode轉換為utf-8

  

s1 = ‘老司機‘
s2 = s1.encode(‘utf-8‘)
print(s2)

  執行輸出:

b‘\xe8\x80\x81\xe5\x8f\xb8\xe6\x9c\xba‘

第二種方法:

s1 = ‘老司機‘
print(bytes(s1,encoding=‘utf-8‘))

  執行輸出:

  b‘\xe8\x80\x81\xe5\x8f\xb8\xe6\x9c\xba‘

 

bytes:只能編碼,將unicode ---> 非unicode bytes(s1,encoding=‘utf-8‘)。

它不能解碼

bytearry:返回一個新字節數組。這個數組裏的元素是可變的,並且每個元素的值範圍: 0 <= x < 256。

bytearry很少用

1 2 3 4 5 6 7 ret = bytearray(‘alex‘,encoding=‘utf-8‘) #4個字母對應的ascii順序[97,108,101,120] print(id(ret)) print(ret) print(ret[0]) #97 是ascii碼的順序 ret[0] = 65 #65是大寫a的位置 print(ret) print(id(ret))

執行輸出:

2177653717736
bytearray(b‘alex‘)
97
bytearray(b‘Alex‘)
2177653717736

memoryview:本函數是返回對象obj的內存查看對象。所謂內存查看對象,就是對象符合緩沖區協議的對象,為了給別的代碼使用緩沖區裏的數據,而不必拷貝,就可以直接使用。

1 2 3 4 5 6 ret = memoryview(bytes(‘你好‘,encoding=‘utf-8‘)) print(len(ret)) # utf-8的bytes類型,放在一個list中 [\xe4,\xbd,\xa0,\xe5,\xa5,\xbd] print(ret) print(bytes(ret[:3]).decode(‘utf-8‘)) print(bytes(ret[3:]).decode(‘utf-8‘)) print(‘你好‘.encode(‘utf-8‘))

執行輸出:

6
<memory at 0x0000016FD6AC0108>


b‘\xe4\xbd\xa0\xe5\xa5\xbd‘

?ord:輸入字符找該字符編碼的位置
?chr:輸入位置數字找出其對應的字符
ascii:是ascii碼中的返回該值,不是就返回\u...

1 2 3 4 print(ord(‘a‘)) #ascii碼的位置 print(chr(98)) #98對應a print(ord(‘中‘)) #按照unicode查找 print(ascii(‘中‘)) #不是ascii碼就返回\u...

執行輸出:

97
b
20013
‘\u4e2d‘

#%r 原封不動的寫出來
name = ‘taibai‘
print(‘我叫%r‘ % name)

#repr原形畢露
print(repr(‘{"name":"alex"}‘))
print(‘{"name":"alex"}‘)

執行輸出:

我叫‘taibai‘
‘{"name":"alex"}‘
{"name":"alex"}

repr在面向對象中會用到

數據集合
???dict:創建一個字典。
???set:創建一個集合。
frozenset:返回一個凍結的集合,凍結後集合不能再添加或刪除任何元素。
相關內置函數

???len:返回一個對象中元素的個數。
???sorted:對所有可叠代的對象進行排序操作。  

li = [1,2,3,4,5,6,7,8]
print(sorted(li))

執行輸出:

[1, 2, 3, 4, 5, 7, 8]

  

按照絕對值排序

1 2 li = [1,-2,-7,8,5,-4,3] print(sorted(li,reverse=True,key=abs))

執行輸出:

[8, -7, 5, -4, 3, -2, 1]

#enumerate 枚舉,返回一個枚舉對象
li = [‘jack‘, ‘rose‘, ‘wusir‘, ‘嫂子‘, ‘老司機‘]
print(enumerate(li))
print(‘__iter__‘ in dir(enumerate(li)))
print(‘__next__‘ in dir(enumerate(li)))

  執行輸出:

<enumerate object at 0x000001D636C20AF8>
True
True

enumerate是一個叠代器

1 2 3 li = [‘jack‘, ‘rose‘, ‘wusir‘, ‘嫂子‘, ‘老司機‘] for i in enumerate(li): print(i)

執行輸出:

(0, ‘jack‘)
(1, ‘rose‘)
(2, ‘wusir‘)
(3, ‘嫂子‘)
(4, ‘老司機‘)

返回結果為:列表元素的索引以及對應的值

1 2 3 li = [‘jack‘, ‘rose‘, ‘wusir‘, ‘嫂子‘, ‘老司機‘] for k,v in enumerate(li): print(k,v)

執行輸出:

0 jack
1 rose
2 wusir
3 嫂子
4 老司機

enumerate的第2個參數,表示從多少開始。默認從1開始

1 2 3 li = [‘jack‘, ‘rose‘, ‘wusir‘, ‘嫂子‘, ‘老司機‘] for k,v in enumerate(li,10): print(k,v)

執行輸出:

10 jack
11 rose
12 wusir
13 嫂子
14 老司機

?all:可叠代對象中,全都是True才是True
?any:可叠代對象中,有一個True 就是True

print(all([1,2,True,0]))
print(any([1,‘‘,0]))

執行輸出:

False
True

???zip:函數用於將可叠代的對象作為參數,將對象中對應的元素打包成一個個元組,然後返回由這些元組組成的列表。如果各個叠代器的元素個數不一致,則返回列表長度與最短的對象相同。

print(‘__iter__‘ in dir(zip(l1,l2,l3,l4))) print(‘__next__‘ in dir(zip(l1,l2,l3,l4)))

執行輸出:

True
True

zip也是一個叠代器

zip 拉鏈方法 形成元組的個數與最短的可叠代對象的長度一樣

1 2 3 4 5 6 l1 = [1, 2, 3, 4] l2 = [‘a‘, ‘b‘, ‘c‘, 5] l3 = (‘*‘, ‘**‘, (1,2,3), 777) z = zip(l1,l2,l3) for i in z: print(i)

執行輸出:

(1, ‘a‘, ‘*‘)
(2, ‘b‘, ‘**‘)
(3, ‘c‘, (1, 2, 3))
(4, 5, 777)

我們把list當做列向量來看就很好理解了,zip就是拉鏈,把一件掛著的衣服拉起來。這就是zip的功能。所以
當做列向量看,就是拉起來的拉鏈了。
而轉置的z就是把拉鏈放水平,多形象!

zip結果取決於最短的一個,返回的數據是元組
面試題,必考zip

???filter:過濾·。
filter 過濾 通過你的函數,過濾一個可叠代對象,返回的是True
類似於[i for i in range(10) if i > 3]

# 取列表中的偶數

def func(x):
    return x % 2 == 0
ret = filter(func,[1,2,3,4,5,6,7])
print(ret)
for i in ret:
    print(i)  

執行輸出:

<filter object at 0x0000021325A4B6D8>
2
4
6

使用列表生成式完成上面的功能

li = [i for i in [1,2,3,4,5,6,7] if i % 2 == 0]
print(li)

執行輸出,效果同上

???map:會根據提供的函數對指定序列做映射。
map相當於列表生成式循環模式

def square(x): #計算平方數
    return x ** 2
ret = map(square,(1,2,3,4,5))
for i in ret:
    print(i)  

執行輸出:

1
4
9
16
25

map也是叠代器

匿名函數
匿名函數:為了解決那些功能很簡單的需求而設計的一句話函數。

返回一個數的平方

使用函數方式

def func1(x)
    return x ** 2

使用匿名函數一行搞定

func = lambda x:x ** 2
print(func(5))

  執行輸出:25

技術分享圖片

上面是我們對calc這個匿名函數的分析,下面給出了一個關於匿名函數格式的說明

1 2 3 4 5 函數名 = lambda 參數 :返回值 #參數可以有多個,用逗號隔開 #匿名函數不管邏輯多復雜,只能寫一行,且邏輯執行結束後的內容就是返回值 #返回值和正常的函數一樣可以是任意數據類型

 

def func2(x+y):
    return x + y

  改成匿名函數

fun = lambda x,y:x+y
print(fun(1,3))

 執行輸出:4

lambda單獨拿出來,沒有啥意義

主要是和內置函數結合使用

lambda函數與內置函數的結合

sorted, map, fiter, max, min, reversed

比較字典值的大小,並輸出key的值

1 2 dic={‘k1‘: 10, ‘k2‘: 100, ‘k3‘: 30} print(max(dic, key=lambda x: dic[x]))

執行輸出: k2

(列表推導式,生成器表達式,內置函數)