解析式
標簽(空格分隔): Python-解析式
目錄
一、解析式
1、列表解析式
-
生成一個列表, 元素 0~9,最每一個元素自增 1后,求平方,返回列表
# 普通實現 lst = [] for i in range(10): lst.append((i+1)**2) # 列表解析式實現 lst = [(i+1)**2 for i in range(10)]
-
語法
[返回值 for 元素 in 可迭代對象 if 條件]
- 使用中括號 [], 內部式
for
循環 ,if 條件語句可選
- 立即返回一個新列表
-
列表解析式是一種語法糖
- 編譯器會優化,不會因為簡寫而影響效率, 反而因優化而提高了效率
- 減少程序員工作量,減少出錯
- 簡化代碼,增加可讀性
列表解析式進階
-
語法
[expr for i in iterable1 for j in iterable2]
- 等價寫法:
lst = [] for i in itersble1: for j in iterable2: lst.append((x, y))
-
語法
[expr for i in iterable1 if cond1 if cond2]
- 等價寫法:
lst = [] for i in itersble1: if cond1: if cond2: lst.append(i) >>> 等價於 for i in iterable1: if cond1 and cond2: lst.append(i)
練習題
-
返回 1-10 平方的列表
print([i**2 for i in range(1, 11)])
-
有一個列表 lst = [1, 4, 9, 16, 2, 5, 10, 15],生成一個新列表,要求新元素是lst相鄰2項的和
lst = [1, 4, 9, 16, 2, 5, 10, 15] length = len(lst) print([lst[i]+lst[i+1] for i in range(length-1)])
-
打印 九九乘法表
[print("{}x{}={:>{}}{}".format(j, i, i*j, 1 if j == 1 else 2, "\n" if i==j else ' '), end="") for i in range(1, 10) for j in range(1, i+1)]
-
打印ID, 要求左邊4位是從1開始的整數,右邊是10位隨機小寫英文字母,中間以點分隔; 打印前100個
import string from random import choice [print(".".join(["{:0>4}".format(i), "".join(choice(string.ascii_lowercase) for _ in range(10))])) for i in range(100)]
2、集合解析式
語法
{返回值 for 元素 in 可迭代對象 if 條件}
- 列表解析式的中括號換成大括號就可以了
- 立即返回一個集合
用法
{(x, x+1) for x in range(10)}
{for x in range(10)}
# 錯誤用法,集合的元素必須是可哈希的
3、字典解析式
語法
{返回值 for 元素 in 可迭代對象 if 條件}
- 列表解析式的中括號換成大括號就可以了
- 使用
key:value
形式 - 立即返回一個字典
用法
{x: (x, x+1) for x in range(10)}
{x: [x, x+1] for x in range(10)}
{(x,): [x, x+1] for x in range(10)}
{[x]: [x, x+1] for x in range(10)}
# 錯誤用法,不可哈希{chr(0x41+x): x**2 for x in range(10)}
{str(x): y for i in range(3) for y in range(4)}
二、生成器表達式
1、生成器表達式語法
(返回 for 元素 in 可迭代對象 if 對象)
- 列表解析式的中括號換成小括號就可以了
- 返回一個生成器 (可迭代對象,迭代器)
使用 內建函數
next()
來判斷一個對象是不是生成器
使用 內建函數iter()
將一個對象編程一個生成器對象
2、實例
# 生成器表達式使用
g = ("{:04}".format(i) for i in range(1, 11))
next(g)
for i in g:
print(i)
print("~~~~~~~~~~~")
for i in g:
print(i)
# 總結
# - 延遲計算
# - 返回一個迭代器,可以迭代
# - 從前到后走完一遍后,不能回頭
# 列表生成器
g = ["{:04}".format(i) for i in range(1, 11)]
next(g)
for i in g:
print(i)
print("~~~~~~~~~~~")
for i in g:
print(i)
# 總結
# - 立即計算
# - 返回的不是一個迭代器,而是一個可以迭代對象列表
# - 從前到后走完一遍后,可以重新回頭迭代
三、和列表解析式的區別
- 生成器表達式是按需計算 (或惰性求值、延遲計算) --- 需要的時候才計算
- 列表解析式是立即返回值
四、和列表解析式的對比
1、計算方式
- 生成器表達式延遲計算,列表解析式立即計算
2、內存占用
- 單從返回值本身來說,生成器表達式省內存, 列表解析式返回新的列表
- 生成器沒有數據,內存占用極少,但是使用的時候,雖然一個個返回數據,但是合起來占用的內存也差不多
- 列表解析式構造新的列表,立即返回,在同一時間下需要占用大量內存; 而生成器則分散了計算時間和占用的空間
3、計算速度
- 單從計算時間看,生成器表達式耗時非常短,列表解析式耗時長
- 但是生成器本身並沒有返回任何值,只返回了一個生成器對象
- 列表解析式構造並返回一個新的列表
五、總結
- python2 引入 列表解析式
- python2.4 引入 生成器表達式
- python3 應用集合、字典解析式、並遷移到了 2.7
1、一般來說,應該多用解析式,因為解析式簡短、高效 (解釋器會做優化)
2、如果一個解析式非常復雜,難以讀懂,要考慮拆解成 for 循環
生成器和迭代器是不同的對象,但都是可迭代對象