列表解析式
列表解析式的語法:[返回值 for 元素 in 可迭代對象 if 條件],使用中括號[],內部是for循環,if條件語句可選,返回一個新的列表 。
列表解析式是一種語法糖,編譯器會優化,不會因為簡寫而影響效率,反而因優化提高了效率。減少程序員工作量,減少出錯。簡化了代碼,但可讀性增強。
比如要生成一個列表,元素0~9,對每一個元素自增1后求平方返回新列表,下面看不用列表解析式和用列表解析式的代碼。
#不用列表解析式 l1 = list(range(10)) l2 = [] for i in l1: l2.append((i+1)**2) print(l2) #用列表解析式 l2 = [(i+1)**2 for i in range(10)] print(l2) print(type(l2)) 結果為: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] <class 'list'>
可以看到可讀性更高,同時也減少了代碼量。比如如果要獲取10以內的偶數。
#不用列表解析 even = [] for i in range(10): if i%2==0: even.append(i) print(even) #用列表解析 [i for i in range(10) if i%2==0]
結果為:
有這樣的賦值語句newlist = [print(i) for i in range(10)],請問newlist的元素打印出來是什么?
newlist = [print(i) for i in range(10)] print(newlist) 結果為: 0 1 2 3 4 5 6 7 8 9 [None, None, None, None, None, None, None, None, None, None]
應該注意if條件后面不能在跟elif,比如獲取20以內的偶數,如果數是3的倍數也打印,下面的代碼是不行的。
[i for i in range(20) if i%2==0 elif i%3==0] 結果為: File "<ipython-input-110-8aea5f5e5abc>", line 1 [i for i in range(20) if i%2==0 elif i%3==0] ^ SyntaxError: invalid syntax
列表解析式進階
[expr for item in iterable if cond1 if cond2] 這等價於:
ret = []
for item in iterable:
if cond1:
if cond2:
ret.append(expr)
比如20以內,既能被2整除又能被3整除的數。
[i for i in range(20) if i%2==0 and i%3==0] 結果為: [0, 6, 12, 18] [i for i in range(20) if i%2==0 if i%3==0] 結果為: [0, 6, 12, 18]
[expr for i in iterable1 for j in iterable2 ] 等價於:
ret = []
for i in iterable1:
for j in iterable2:
ret.append(expr)
相當於嵌套for循環。
[(x, y) for x in 'abcde' for y in range(3)] 結果為: [('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2), ('c', 0), ('c', 1), ('c', 2), ('d', 0), ('d', 1), ('d', 2), ('e', 0), ('e', 1), ('e', 2)] [[x, y] for x in 'abcde' for y in range(3)] 結果為: [['a', 0], ['a', 1], ['a', 2], ['b', 0], ['b', 1], ['b', 2], ['c', 0], ['c', 1], ['c', 2], ['d', 0], ['d', 1], ['d', 2], ['e', 0], ['e', 1], ['e', 2]] [{x: y} for x in 'abcde' for y in range(3)] 結果為: [{'a': 0}, {'a': 1}, {'a': 2}, {'b': 0}, {'b': 1}, {'b': 2}, {'c': 0}, {'c': 1}, {'c': 2}, {'d': 0}, {'d': 1}, {'d': 2}, {'e': 0}, {'e': 1}, {'e': 2}]
[(i,j) for i in range(7) if i>4 for j in range(20,25) if j>23] [(i,j) for i in range(7) for j in range(20,25) if i>4 if j>23] [(i,j) for i in range(7) for j in range(20,25) if i>4 and j>23] 結果都為: [(5, 24), (6, 24)]
練習題:
- 返回1-10平方的列表
- 有一個列表lst = [1,4,9,16,2,5,10,15],生成一個新列表,要求新列表元素是lst相鄰2項的和
- 打印九九乘法表
- "0001.abadicddws" 是ID格式,要求ID格式是以點號分割,左邊是4位從1開始的整數,右邊是10位隨機小寫英文字母。請依次生成前100個ID的列表
#返回1-10平方的列表 [i**2 for i in range(1,11)] 結果為: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] #有一個列表lst = [1,4,9,16,2,5,10,15],生成一個新列表,要求新列表元素是lst相鄰2項的和 lst = [1,4,9,16,2,5,10,15] [lst[i]+lst[i+1] for i in range(len(lst)-1)] 結果為: [5, 13, 25, 18, 7, 15, 25] #打印九九乘法表 print("\n".join(["".join(["%s*%s=%-3s" %(x,y,y*x) for x in range(1,y+1)]) for y in range(1,10)])) 結果為: 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 [print("{}*{}={:<3}{}".format(j,i,i*j,"\n" if i==j else ""),end="") for i in range(1,10) for j in range(1,i+1)] 結果為: 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
import random ["{:04}.{}".format(n,"".join([random.choice(bytes(range(97,123)).decode()) for _ in range(10)])) for n in range(1,101)] import random ["{:04}.{}".format(i,"".join([chr(random.randint(97,122)) for j in range(10)])) for i in range(1,101)] import string ["{:>04}.{}".format(i,"".join((random.choice(string.ascii_lowercase)) for _ in range(0,10))) for i in range(1,101)] 以上三種方法都能生成