Python之列表推導式最全匯總(中篇)
前言
網(wǎng)傳的七天學Python的路線如下,我覺得可以在學過此表中前幾天的內(nèi)容后,就可以回頭來學習一下
列表推導式:它綜合了列表、for循環(huán)和條件語句。
第一天:基本概念(4小時) : print,變量,輸入,條件語句。
第二天:基本概念(5小時) :列表,for循環(huán),while循環(huán),函數(shù),導入模塊。
第三天:簡單編程問題(5小時) :交換兩個變量值,將攝氏度轉換為華氏溫度,求數(shù)字中各位數(shù)之和, 判斷某數(shù)是否為素數(shù), 生成隨機數(shù),刪除列表中的重復項等等。
第四天:中級編程問題(6小時) :反轉-個字符串(回文檢測),計算最大公約數(shù),合并兩個有序數(shù)組,猜數(shù)字游戲,計算年齡等等。
第五天:數(shù)據(jù)結構(6小時) :棧,隊列,字典,元組,樹,鏈表。
第六天:面向對象編程(OOP) (6小時) :對象,類,方法和構造函數(shù),面向對象編程之繼承。
第七天:算法(6小時) :搜索(線性和二分查找)、 排序(冒泡排序、 選擇排序)、遞歸函數(shù)(階乘、斐波那契數(shù)列)時間復雜度(線性、二次和常量)。
列表推導式
- list comprehension或譯為列表解析式,是一種創(chuàng)建列表的簡潔語法;
- 也可認為它是一個簡版的for循環(huán),但執(zhí)行效率高于for循環(huán)。
- python 2.7+ 開始又引入了集合推導式、字典推導式,原理與列表推導式相近。
語法規(guī)范:
out_list = [out_express for out_express in input_list if out_express_condition]
其中,
- if 條件可有可無;
- for 循環(huán)可以嵌套多層,內(nèi)外層循環(huán)的變量不可以同名;
- 推導式中也可以嵌套推導式,內(nèi)外層推導式的變量互不影響,可以同名;
- 推導表達式out_express盡可能用內(nèi)置函數(shù),省得import或def function()。
初階實例
1000~2021中包含7的數(shù)字有多少
>>> sum([1 for i in range(1000,2022) if '7' in str(i)]) 273 >>> [i for i in range(1000,2022) if '7' in str(i)] [1007, 1017, 1027, 1037, 1047, 1057, 1067, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1087, 1097, 1107, 1117, 1127, 1137, 1147, 1157, 1167, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1187, 1197, 1207, 1217, 1227, 1237, 1247, 1257, 1267, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1287, 1297, 1307, 1317, 1327, 1337, 1347, 1357, 1367, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1387, 1397, 1407, 1417, 1427, 1437, 1447, 1457, 1467, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1487, 1497, 1507, 1517, 1527, 1537, 1547, 1557, 1567, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1587, 1597, 1607, 1617, 1627, 1637, 1647, 1657, 1667, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1687, 1697, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1807, 1817, 1827, 1837, 1847, 1857, 1867, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1887, 1897, 1907, 1917, 1927, 1937, 1947, 1957, 1967, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1987, 1997, 2007, 2017] >>>
1000~2021中“包含7且能被7整除”的數(shù)字有多少
>>> sum([1 for i in range(1000,2022) if '7' in str(i) and i%7==0]) 39 >>> [i for i in range(1000,2022) if '7' in str(i) and i%7==0] [1057, 1071, 1078, 1127, 1176, 1197, 1267, 1274, 1337, 1372, 1379, 1407, 1470, 1477, 1547, 1575, 1617, 1673, 1687, 1701, 1708, 1715, 1722, 1729, 1736, 1743, 1750, 1757, 1764, 1771, 1778, 1785, 1792, 1799, 1827, 1876, 1897, 1967, 1974] >>>
小于1000000的所有正整數(shù)一共包含有多少個數(shù)字“7”
>>> num=lambda n:sum([str(i).count('7') for i in [i for i in range(1,n+1)] if '7' in str(i)]) >>> num(999999) 600000 >>> # if '7' in str(i) 可省掉,即0也合計結果一樣
求所有在100到1000之間的水仙花數(shù)
水仙花數(shù)定義:指一個正整數(shù)的各位數(shù)字的立方和等于其本身。
通常的解法,條件表達式比較麻,如果是10位數(shù)呢
>>> for i in range(100,1000): if i==(i //100)**3 + (i//10%10)**3 + (i%10)**3: print(i, end=' ') 153 370 371 407 >>> >>> # 改寫成列表推導式: >>> [i for i in range(100,1000) if i==(i //100)**3 + (i//10%10)**3 + (i%10)**3] [153, 370, 371, 407] >>>
把數(shù)字轉成字符串,然后遍歷計算立方和
>>> >>> for i in range(100,1000): k=0 for j in str(i): k+=int(j)**3 if k==i: print(i,end=' ') 153 370 371 407 >>> >>> # 轉成列表推導式: >>> [n for i,n in enumerate([sum([int(i)**3 for i in str(j)]) for j in range(100,1000)]) if i+100==n] [153, 370, 371, 407] >>>
一維與二維列表間的互轉
>>> *a,=range(1,10) >>> a [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> b=[a[i:i+3] for i in range(0,len(a),3)] >>> b [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> >>> c=[j for i in b for j in i] >>> c [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> >>> sum(b,[]) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> # 很高級的方法 # pythonic
實現(xiàn)二維列表的轉置
行列互換,首行變首列,尾行變尾列,如下所示:
''''''''''''''''''' [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] ↓↓↓ [ [1, 4, 7], [2, 5, 8], [3, 6, 9] ] 推導式如下: ''''''''''''''''''' >>> arr=[[1,2,3], [4,5,6], [7,8,9]] >>> [[arr[i][j] for i in range(len(arr))] for j in range(len(arr[0]))] [[1, 4, 7], [2, 5, 8], [3, 6, 9]] >>>
使用zip()函數(shù):優(yōu)點不用考慮數(shù)組的行數(shù)和列數(shù),但直接結果是元組的列表,需轉換下
>>> arr=[[1,2,3], [4,5,6], [7,8,9]] >>> list(zip(*arr)) [(1, 4, 7), (2, 5, 8), (3, 6, 9)] >>> >>> arr=[[1,2,3], [4,5,6], [7,8,9]] >>> arr=[list(i) for i in zip(*arr)] >>> arr [[1, 4, 7], [2, 5, 8], [3, 6, 9]] >>> arr=[list(i) for i in zip(*arr)] >>> arr [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> # 換一個3行4列的: >>> arr=[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] >>> arr=[list(i) for i in zip(*arr)] >>> arr [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] >>> arr=[list(i) for i in zip(*arr)] >>> arr [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] >>>
使用numpy庫:特有numpy.array()可與list()相互轉換
>>> import numpy as np >>> np.arange(1,10) array([1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> # 或者: >>> np.array([*range(1,10)]) array([1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> >>> list(np.arange(1,10)) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> >>> np.arange(1,10).reshape((3, 3)) array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> arr=np.arange(1,10).reshape((3, 3)) >>> [list(i) for i in arr] [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> >>> [j for i in arr for j in i] [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> # 附:用numpy生成一個3行5列的隨機數(shù)矩陣,數(shù)值范圍[1,10): >>> [list(i) for i in __import__('numpy').random.randint(1,10,(3,5))] [[6, 3, 6, 7, 8], [4, 9, 5, 8, 7], [8, 4, 1, 2, 1]] >>>
求列表嵌套的最大深度
思路:遍歷列表,只要還有一個元素是列表,就刪除非列表元素然后進行降維;循環(huán)到所有元素都為非列表為止。
代碼如下,自定義函數(shù)就用了兩個推導式一個循環(huán)語句
>>> def func(L): if not isinstance(L,list): # or: if type(L) is not list: return 0 k=1 while any([isinstance(i,list) for i in L]): k+=1 L=[j for i in [i for i in L if isinstance(i,list)] for j in i] return k >>> l = [1, 2, [3, [4, [5, 6], [7, [8], [[9, 10], [11, [12, 13, 14], 15]]]]]] >>> func(l) 7 >>>
注:內(nèi)置函數(shù) isinstance(i,list) 判斷一個對象i是否為某個指定類型,等價于type(i) is list。
例如: isinstance(123,int) 和 type(123) is int 都返回True。
求斜邊長小于100的勾股數(shù)組
代碼如下,其中 A 有直角邊互換的重復,B用條件a<b約束,C把約束條件放進 range() 函數(shù)中。
>>> A=[(a,b,c) for a in range(1,100) for b in range(1,100) for c in range(1,100) if a**2+b**2==c**2] >>> B=[(a,b,c) for a in range(1,100) for b in range(1,100) for c in range(1,100) if a<b and a**2+b**2==c**2] >>> C=[(a,b,c) for a in range(1,100) for b in range(a,100) for c in range(1,100) if a**2+b**2==c**2] >>> A==B False >>> len(A)==len(B)*2 True >>> B==C True >>> C [(3, 4, 5), (5, 12, 13), (6, 8, 10), (7, 24, 25), (8, 15, 17), (9, 12, 15), (9, 40, 41), (10, 24, 26), (11, 60, 61), (12, 16, 20), (12, 35, 37), (13, 84, 85), (14, 48, 50), (15, 20, 25), (15, 36, 39), (16, 30, 34), (16, 63, 65), (18, 24, 30), (18, 80, 82), (20, 21, 29), (20, 48, 52), (21, 28, 35), (21, 72, 75), (24, 32, 40), (24, 45, 51), (24, 70, 74), (25, 60, 65), (27, 36, 45), (28, 45, 53), (30, 40, 50), (30, 72, 78), (32, 60, 68), (33, 44, 55), (33, 56, 65), (35, 84, 91), (36, 48, 60), (36, 77, 85), (39, 52, 65), (39, 80, 89), (40, 42, 58), (40, 75, 85), (42, 56, 70), (45, 60, 75), (48, 55, 73), (48, 64, 80), (51, 68, 85), (54, 72, 90), (57, 76, 95), (60, 63, 87), (65, 72, 97)]
實現(xiàn)隨機字符串(可作隨機密碼)
>>> import string,random >>> [''.join(random.sample(string.printable[:-6],10)) for _ in range(30)] ['\\T[~(]J#"+', '):0~He7Dam', 'zw=?>7a(&^', 'v<c@W:!&VP', 'y\\~W6{u:P1', 'R)il~3p+;y', "PGQ_'{.k15", 'Z"^w=P&3{R', 'yMGR[g_65$', "4.)Q7$COd'", 'WTptgYS$Nj', 'Ra$4Lrvu2)', ',V$z.C8>L(', '/YwfR#ZuM@', '>~){Q7ayUo', 'Ol]54z|a;\\', 'Dp80fV,\\-@', '[kB{he98&r', "E]$'Q@R-`0", 'm{qMBRD.p2', '=.Is;r>%/x', 'o7zS{DQ~Tx', 'hH:E{s?#Gt', 'WB]`%\\f.FT', 'Mbxu&8YEN_', '5Et+3dGAf%', 'k5#o_]2Y?T', '$K3(yD7wvJ', '^5kJ*Nn:jz', '8,q7/Oyb*3'] >>> >>> [''.join(random.sample(string.ascii_letters+string.digits*5,10)) for _ in range(30)] ['ugON2AoS10', '3E62mQ2sP8', 'sL76c4Ppyj', 'hS967O15bX', '7n8580rq01', 'B75C178051', '8Mvc0g52wd', 'Zv08H3GED8', '158F1Kd36o', '914FM222TK', 'n5I5aqY66h', '91Tz8P5yMf', '22K9tPLoHn', 'gR5862BZj9', '319pO53389', 'z31R67r811', 'E1duG7mzPS', 't6kx344cCU', '3b66u5yOc3', '387s3bj031', 'J665322viO', 'N4Y76QmfO9', '9d4038O7fD', '2lQ8D41z3G', 'l03P7146G4', 'n716wj2b9c', '4av2g6dDb7', '6q65ro2z43', 'LJC77i56xq', 'hHBGA547a5'] >>>
不使用string庫,只用字母、數(shù)字和下劃線:
>>> pwd = lambda x=10:[''.join(__import__('random').sample((*map(chr,[*range(48,58),*range(65,91),*range(97,123)]),'_'),8)) for _ in range(x)] >>> >>> print(*pwd()) NVKfO5Du HxT2qSJF _GzK1kD3 KVw1OWjB Ob8fRswa MFqvpEWK fPDzuj8e ZndGFAs7 VHMp3FtX Hc7o642q >>> print(*pwd()) c2HEwvkn I9wH1Vjm yOCaqzNR pXMqRuDg nUfTKXuV Co5Ebq7g mBCkDco1 ieUzSTpu y1s8zVct OiK3GFTw >>> print(*pwd(5)) xTd69oJW Ob6pFsaq 4XW5lw_Y aHJxiZgr Z0VAGhNB >>> print(*pwd(8)) BP1bpzlv VBvnFQE5 kmFZSLid WyCpqvK_ vOyQlB4c VSY8q67y 8lkGBRbt _I4MfqJk
一個四層嵌套的推導式:求k等差數(shù)
“k等差數(shù)”定義:任意相鄰兩位之間的差的絕對值都為 k 的正十進制整數(shù)。
給定整數(shù)的位數(shù) n 和 等差值 k,求所有 k等差數(shù):
>>> iscdnum = lambda n,k:[num for num in range(10**(n-1),10**n) if all([i==k for i in [abs(int(j[0])-int(j[1])) for j in [str(num)[i:i+2] for i in range(len(str(num))-1)]]])] >>> iscdnum(2,5) [16, 27, 38, 49, 50, 61, 72, 83, 94] >>> iscdnum(3,2) [131, 135, 202, 242, 246, 313, 353, 357, 420, 424, 464, 468, 531, 535, 575, 579, 642, 646, 686, 753, 757, 797, 864, 868, 975, 979] >>> iscdnum(3,3) [141, 147, 252, 258, 303, 363, 369, 414, 474, 525, 585, 630, 636, 696, 741, 747, 852, 858, 963, 969] >>> iscdnum(3,4) [151, 159, 262, 373, 404, 484, 515, 595, 626, 737, 840, 848, 951, 959] >>> iscdnum(3,9) [909] >>> iscdnum(5,2) [13131, 13135, 13531, 13535, 13575, 13579, 20202, 20242, 20246, 24202, 24242, 24246, 24642, 24646, 24686, 31313, 31353, 31357, 35313, 35353, 35357, 35753, 35757, 35797, 42020, 42024, 42420, 42424, 42464, 42468, 46420, 46424, 46464, 46468, 46864, 46868, 53131, 53135, 53531, 53535, 53575, 53579, 57531, 57535, 57575, 57579, 57975, 57979, 64202, 64242, 64246, 64642, 64646, 64686, 68642, 68646, 68686, 75313, 75353, 75357, 75753, 75757, 75797, 79753, 79757, 79797, 86420, 86424, 86464, 86468, 86864, 86868, 97531, 97535, 97575, 97579, 97975, 97979] >>>
附錄
到此這篇關于Python之列表推導式最全匯總(中篇)的文章就介紹到這了,其他兩個部分的內(nèi)容(上、下篇)請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python實現(xiàn)如何根據(jù)文件后綴進行分類
本文主要為大家詳細介紹了如何通過python實現(xiàn)根據(jù)文件后綴實現(xiàn)分類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以關注一下2021-12-12python 實現(xiàn)selenium斷言和驗證的方法
今天小編就為大家分享一篇python 實現(xiàn)selenium斷言和驗證的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-02-02