解析式、表達式


解析式

標簽(空格分隔): 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 循環

生成器和迭代器是不同的對象,但都是可迭代對象


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM