Python 彻底搞懂列表推导式|初级到进阶(实例30+)

简介: Python 彻底搞懂列表推导式|初级到进阶(实例30+)

前言


  网传的七天学Python的路线如下,我觉得可以在学过此表中前几天的内容后,就可以回头来学习一下列表推导式:它综合了列表、for循环和条件语句。


第一天:基本概念(4小时) : print,变量,输入,条件语句。


第二天:基本概念(5小时) :列表,for循环,while循环,函数,导入模块。


第三天:简单编程问题(5小时) :交换两个变量值,将摄氏度转换为华氏温度,求数字中各位数之和, 判断某数是否为素数, 生成随机数,删除列表中的重复项等等。


第四天:中级编程问题(6小时) :反转-个字符串(回文检测),计算最大公约数,合并两个有序数组,猜数字游戏,计算年龄等等。


第五天:数据结构(6小时) :栈,队列,字典,元组,树,链表。


第六天:面向对象编程(OOP) (6小时) :对象,类,方法和构造函数,面向对象编程之继承。


第七天:算法(6小时) :搜索(线性和二分查找)、 排序(冒泡排序、 选择排序)、递归函数(阶乘、斐波那契数列)时间复杂度(线性、二次和常量)。



列表推导式


list comprehension或译为列表解析式,是一种创建列表的简洁语法;也可认为它是一个简版的for循环,但执行效率高于for循环。python 2.7+ 开始又引入了集合推导式、字典推导式,原理与列表推导式相近。


语法规范:


out_list = [out_express for out_express in input_list if out_express_condition]

其中,if 条件可有可无;for 循环可以嵌套多层,内外层循环的变量不可以同名;

  推导式中也可以嵌套推导式,内外层推导式的变量互不影响,可以同名;

  推导表达式out_express尽可能用内置函数,省得import或def function()。



入门实例

>>> [i for i in range(20)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> [i for i in range(40) if i%2==0]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38]
>>> [i*2 for i in range(20)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38]
>>> [i+j for i in range(5) for j in range(5)]
[0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]
>>> [i+j for i in range(10) for j in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6,
 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 5, 6, 7, 8, 9, 10, 11,
 12, 13, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 6, 7, 8, 9, 10, 11, 12, 13, 14,
 15, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
>>> {i+j for i in range(10) for j in range(10)}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
>>> [(i,j,k) for i in 'abc' for j in range(2) for k in range(2)]
[('a', 0, 0), ('a', 0, 1), ('a', 1, 0), ('a', 1, 1), ('b', 0, 0), ('b', 0, 1),
 ('b', 1, 0), ('b', 1, 1), ('c', 0, 0), ('c', 0, 1), ('c', 1, 0), ('c', 1, 1)]
>>> [chr(i) for i in range(97,123)]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
>>> {i:ord(i) for i in [chr(i) for i in range(97,123)]}
{'a': 97, 'b': 98, 'c': 99, 'd': 100, 'e': 101, 'f': 102, 'g': 103, 'h': 104,
 'i': 105, 'j': 106, 'k': 107, 'l': 108, 'm': 109, 'n': 110, 'o': 111, 'p': 112,
 'q': 113, 'r': 114, 's': 115, 't': 116, 'u': 117, 'v': 118, 'w': 119, 'x': 120,
 'y': 121, 'z': 122}
>>> dic={i:ord(i) for i in [chr(i) for i in range(97,123)]}
>>> dic['x']
120
>>> 


注:

  列表推导式外用‘[...]’,换成‘{...}’就是集合推导式;有键值对就是字典推导式。

  推导式外用‘(...)’会得到一个“生成器”,如果需要“元组推导式”另要用tuple()函数转换;

  生成器还有一个特性,只能被遍历一次,遍历过后就会被清空。

>>> (i for i in range(20))
<generator object <genexpr> at 0x0000000002CF3890>
>>> type(i for i in range(20))
<class 'generator'>
>>> tuple(i for i in range(20))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
>>> 
>>> g = (i for i in range(10))
>>> g
<generator object <genexpr> at 0x03CE71E8>
>>> a = [i for i in g]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b = [i for i in g]
>>> b
[]
>>> 



生成过程:


>>> [i for i in range(10)]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#这个推导式用for循环赋值的代码:


1. my_list = []
2. for i in range(10):
3.     my_list.append(i)
4. print(my_list)



注:当然这么简单的列表,可以不用推导式更不需要写代码来生成。

  python有更加省事的方法来直接赋值:


方法一:

1. >>> a = []; a[:] = range(10)
2. >>> a
3. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4. >>>



方法二:此方法是我在学习用星号“*”给序列解包时偶尔试出来的

>>> *a,=range(10)  # 此处变量a后的逗号“,”必不可少
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
>>> # 或者:
>>> a = [*range(10)]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
>>> # 若要取部分,把不要的元素“赋值”给下划线 _
>>> _,*a=range(10)
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
>>> # 元组的赋值,结尾用逗号:
>>> tp = *range(1,11),
>>> tp
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> 



序列解包 * :

>>> Cards = [*range(2,10),*list('TJQKA')]
>>> Cards
[2, 3, 4, 5, 6, 7, 8, 9, 'T', 'J', 'Q', 'K', 'A']
>>> Cards = *range(2,10),*tuple('TJQKA')
>>> Cards
(2, 3, 4, 5, 6, 7, 8, 9, 'T', 'J', 'Q', 'K', 'A')
>>>  # tuple 赋值时连最外的()都可以省掉


map()函数解包 *

1. >>> n = 12345678
2. >>> [int(i) for i in str(n)]
3. [1, 2, 3, 4, 5, 6, 7, 8]
4. >>> [*map(int,str(n))]
5. [1, 2, 3, 4, 5, 6, 7, 8]
6. >>>



还有一个特别的:单循环的变量可用 _ 代替:

>>> [_ for _ in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [_*_ for _ in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [str(_) for _ in range(2,10)]
['2', '3', '4', '5', '6', '7', '8', '9']
>>> 



列表元素间的运算:

# 加法
>>> listAdd = lambda a,b:[i+j for m,i in enumerate(a) for n,j in enumerate(b) if m==n]
>>> a = [1,2,3,4]
>>> b = [2,4,7,11,16]
>>> listAdd(a,b)
[3, 6, 10, 15]
>>> listAdd([0]+a,b)
[2, 5, 9, 14, 20]
>>> listAdd(a,b[1:])
[5, 9, 14, 20]
>>> listAdd(a[1:],b)
[4, 7, 11]
>>> 



# 其它运算
>>> listOP = lambda a,b,c=0:[i-j if c==2 else i*j if c==3 else i/j if c==4 else i//j if c==5 else i%j if c==6 else i+j for m,i in enumerate(a) for n,j in enumerate(b) if m==n]
>>> a = [1,2,3,4]
>>> b = [2,4,7,11,16]
>>> listOP(a,b)
[3, 6, 10, 15]
>>> listOP(a,b,1)
[3, 6, 10, 15]
>>> listOP(a,b,2)
[-1, -2, -4, -7]
>>> listOP(b,a,2)
[1, 2, 4, 7]
>>> listOP(a,b,2)
[-1, -2, -4, -7]
>>> listOP(a,b,3)
[2, 8, 21, 44]
>>> listOP(a,b,4)
[0.5, 0.5, 0.42857142857142855, 0.36363636363636365]
>>> listOP(b,a,4)
[2.0, 2.0, 2.3333333333333335, 2.75]
>>> listOP(a,b,5)
[0, 0, 0, 0]
>>> listOP(b,a,5)
[2, 2, 2, 2]
>>> listOP(b[1:],a,5)
[4, 3, 3, 4]
>>> listOP(a,b,6)
[1, 2, 3, 4]
>>> listOP(b,a,6)
[0, 0, 1, 3]
>>> listOP(b[2:],a,6)
[0, 1, 1]
>>> 





初阶实例


1. 1000~2021中包含7的数字有多少

>>> 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整除”的数字有多少

>>> 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的所有正整数一共包含有多少个数字“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也合计结果一样



2. 求所有在100到1000之间的水仙花数

水仙花数定义:指一个正整数的各位数字的立方和等于其本身。

(1). 通常的解法,条件表达式比较麻,如果是10位数呢

>>> 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]
>>> 



(2). 把数字转成字符串,然后遍历计算立方和

>>> >>> 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]
>>> 


3.  一维与二维列表间的互转

>>> *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



4.  实现二维列表的转置

行列互换,首行变首列,尾行变尾列,如下所示:

'''''''''''''''''''
[ [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()函数:优点不用考虑数组的行数和列数,但直接结果是元组的列表,需转换下

>>> 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列的随机数矩阵,数值范围[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]]
>>> 



5. 求列表嵌套的最大深度

思路:遍历列表,只要还有一个元素是列表,就删除非列表元素然后进行降维;循环到所有元素都为非列表为止。代码如下,自定义函数就用了两个推导式一个循环语句

>>> 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
>>> 


注:内置函数 isinstance(i,list) 判断一个对象i是否为某个指定类型,等价于type(i) is list。例如: isinstance(123,int) 和 type(123) is int 都返回True。



6. 求斜边长小于100的勾股数组

代码如下,其中 A 有直角边互换的重复,B用条件a<b约束,C把约束条件放进 range() 函数中。


>>> 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)]
>>>




7. 实现随机字符串(可作随机密码)

>>> 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库,只用字母、数字和下划线:

>>> 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




8. 一个四层嵌套的推导式:求k等差数

“k等差数”定义:任意相邻两位之间的差的绝对值都为 k 的正十进制整数。

给定整数的位数 n 和 等差值 k,求所有 k等差数:

>>> 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]
>>> 




进阶实例



1. 乘法口诀表

>>> lst=['%sx%s=%s'%(j,i,i*j) for i in range(1,10) for j in range(1,i+1)]
>>> lst
['1x1=1', '1x2=2', '2x2=4', '1x3=3', '2x3=6', '3x3=9', '1x4=4', '2x4=8', '3x4=12', 
'4x4=16', '1x5=5', '2x5=10', '3x5=15', '4x5=20', '5x5=25', '1x6=6', '2x6=12', '3x6=18', 
'4x6=24', '5x6=30', '6x6=36', '1x7=7', '2x7=14', '3x7=21', '4x7=28', '5x7=35', '6x7=42', 
'7x7=49', '1x8=8', '2x8=16', '3x8=24', '4x8=32', '5x8=40', '6x8=48', '7x8=56', '8x8=64', 
'1x9=9', '2x9=18', '3x9=27', '4x9=36', '5x9=45', '6x9=54', '7x9=63', '8x9=72', '9x9=81']


列印时,要注意它的项数通项公式是: An=n(n+1)/2+1

>>> 
for i in range(9):
    for j in range(i+1):
      print(lst[i*(i+1)//2+j],end='\t' if i!=j else '\n')
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12  4x4=16
1x5=5 2x5=10  3x5=15  4x5=20  5x5=25
1x6=6 2x6=12  3x6=18  4x6=24  5x6=30  6x6=36
1x7=7 2x7=14  3x7=21  4x7=28  5x7=35  6x7=42  7x7=49
1x8=8 2x8=16  3x8=24  4x8=32  5x8=40  6x8=48  7x8=56  8x8=64
1x9=9 2x9=18  3x9=27  4x9=36  5x9=45  6x9=54  7x9=63  8x9=72  9x9=81
>>> 



或者用join()直接把 \t \n 插入列表拼接成字符串,然后输出:

>>> print('\n'.join(['\t'.join([f'{j}x{i}={i*j}' for j in range(1,i+1)]) for i in range(1,10)]))
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12  4x4=16
1x5=5 2x5=10  3x5=15  4x5=20  5x5=25
1x6=6 2x6=12  3x6=18  4x6=24  5x6=30  6x6=36
1x7=7 2x7=14  3x7=21  4x7=28  5x7=35  6x7=42  7x7=49
1x8=8 2x8=16  3x8=24  4x8=32  5x8=40  6x8=48  7x8=56  8x8=64
1x9=9 2x9=18  3x9=27  4x9=36  5x9=45  6x9=54  7x9=63  8x9=72  9x9=81
>>> 
>>> # f'{j}x{i}={i*j}'  等价于 '%sx%s=%s'%(j,i,i*j)



2. 求100以内的质数(或称素数)

>>> [k[0] for k in [(j,sum([j%i==0 for i in range(2,j)])) for j in range(2,100)] if k[1]==0]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> 
>>> # 等价于:
>>> [k[0] for k in [(j,sum([0 if j%i else 1 for i in range(2,j)])) for j in range(2,100)] if k[1]==0]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> 

上面两种方法都是累加sum布尔值bool的个数来计算的,可以用any() all()函数代替:

>>> [k[0] for k in [(j,[j%i==0 for i in range(2,j)]) for j in range(2,100)] if not any(k[1])]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>>
>>> # 等价于:
>>> [k[0] for k in [(j,[j%i!=0 for i in range(2,j)]) for j in range(2,100)] if all(k[1])]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> 



使用filter()和map()函数:  

 

[i for i in filter(lambda x:all(map(lambda p:x%p,range(2,x))), range(2,100))]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> 


条件反过来就是100以内的合数:

>>> [k[0] for k in [(j,[j%i==0 for i in range(2,j)]) for j in range(2,100)] if any(k[1])]
[4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35,
 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64,
 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92,
 93, 94, 95, 96, 98, 99]
>>> [k[0] for k in [(j,[j%i!=0 for i in range(2,j)]) for j in range(2,100)] if not all(k[1])]
[4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35,
 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64,
 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92,
 93, 94, 95, 96, 98, 99]
>>> [i for i in filter(lambda x:not all(map(lambda p:x%p,range(2,x))), range(2,100))]
[4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35,
 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64,
 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92,
 93, 94, 95, 96, 98, 99]
>>> 



求1000以内的质回文数(即是质数又是回文数)

>>> Pr=[str(k[0]) for k in [(j,[j%i!=0 for i in range(2,j)]) for j in range(2,1000)] if all(k[1])]
>>> [int(p) for p in Pr if p[::-1] in Pr]
[2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383, 727, 757, 787, 797, 919, 929]



求1000以内的数,满足本身和它的回文数同是质数

>>> pstr=[str(k[0]) for k in [(j,[j%i!=0 for i in range(2,j)]) for j in range(2,1000)] if all(k[1])]
>>> [int(p) for p in pstr if p[::-1] in pstr]
[2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, 97, 101, 107, 113, 131, 149, 151, 157, 167, 
179, 181, 191, 199, 311, 313, 337, 347, 353, 359, 373, 383, 389, 701, 709, 727, 733, 739, 
743, 751, 757, 761, 769, 787, 797, 907, 919, 929, 937, 941, 953, 967, 971, 983, 991]
>>> 



分解质因数(N<2022)

>>> P = [k[0] for k in [(j,sum([j%i==0 for i in range(2,j)])) for j in range(2,2022)] if k[1]==0]
>>>
def func(n):
    res=[]
    t=P[::-1]
    m=t[-1]
    while n>=m:
        if n%m==0:
            n//=m
            res.append(m)
        else:
            t.pop()
            m=t[-1]
    return res
>>> i = 2021
>>> print(i,'=','x'.join([str(j) for j in func(i)]))
2021 = 43x47
>>> 
>>> func(2000)
[2, 2, 2, 2, 5, 5, 5]
>>> func(3999)
[3, 31, 43]
>>> 




3. 求出字符串的所有字串(可推广到所有可切片数据类型)

 

>>> L='abcd'
>>> [L[i:j] for i in range(len(L)) for j in range(i+1,len(L)+1)]
['a', 'ab', 'abc', 'abcd', 'b', 'bc', 'bcd', 'c', 'cd', 'd']
>>> 



注:凡是可以用[i:j]来切片的“容器类”数据类型都可用此推导式。如:


>>> L=[1,2,3,4]
>>> [L[i:j] for i in range(len(L)) for j in range(i+1,len(L)+1)]
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [2], [2, 3], [2, 3, 4], [3], [3, 4], [4]]
>>> 



(1). 找出字符串s='aaabcddcbddba'中最长的回文字串

>>> s='aaabcddcbddba'
>>> {s[i:j] for i in range(len(s)) for j in range(i+1,len(s)+1)}
{'bcddcbdd', 'ddcbddb', 'abcddcbdd', 'aabcddc', 'aabcddcbdd', 'cbddba', 'aaa',
 'cddcbd', 'cbddb', 'a', 'cdd', 'bcdd', 'aabcddcbddba', 'aabcd', 'abcddcbddb',
 'aaabc', 'ab', 'cbdd', 'cddcbdd', 'aaabcddcb', 'aabcddcbd', 'aaabcdd', 'ba',
 'ddcbddba', 'dba', 'db', 'cddcbddba', 'cbd', 'aaabcddcbddb', 'aaabcd', 'ddb',
 'dcbdd', 'abcddc', 'abcd', 'abcdd', 'bcddcb', 'aaabcddcbdd', 'abcddcbddba',
 'aabc', 'bcddc', 'bdd', 'cb', 'bcddcbddba', 'c', 'dcbddb', 'ddba', 'dcbd',
 'b', 'aaab', 'dd', 'd', 'ddcbd', 'bcd', 'aa', 'abcddcbd', 'bcddcbddb',
 'aaabcddcbd', 'cddc', 'ddcb', 'dc', 'abc', 'bddb', 'ddc', 'bcddcbd', 'bc',
 'aabcdd', 'aab', 'aaabcddcbddba', 'cddcb', 'abcddcb', 'cd', 'bddba', 'aabcddcbddb',
 'bd', 'ddcbdd', 'aaabcddc', 'dcb', 'dcbddba', 'aabcddcb', 'cddcbddb'}
>>> # 使用字典推导式可去掉相同子串
>>>
>>> [i for i in {s[i:j] for i in range(len(s)) for j in range(i+1,len(s)+1)} if i==i[::-1]]
['aaa', 'a', 'bcddcb', 'c', 'b', 'dd', 'd', 'aa', 'cddc', 'bddb']
>>> 
>>> [(len(i),i) for i in {i for i in [s[i:j] for i in range(len(s)) for j in range(i+1,len(s)+1)} if i==i[::-1]]]
[(3, 'aaa'), (1, 'a'), (6, 'bcddcb'), (1, 'c'), (1, 'b'), (2, 'dd'), (1, 'd'),
 (2, 'aa'), (4, 'cddc'), (4, 'bddb')]
>>> 
>>> max([(len(i),i) for i in [i for i in {s[i:j] for i in range(len(s)) for j in range(i+1,len(s)+1)} if i==i[::-1]]])[1]
'bcddcb'
>>> 



(2). 给定 L=[2, -3, 3, 50, 5, 0, -1],输出其子序列中各元素合计数最大的子序列

>>> L = [2, -3, 3, 50, 5, 0, -1]
>>> [L[i:j] for i in range(len(L)) for j in range(i+1,len(L)+1)]
[[2], [2, -3], [2, -3, 3], [2, -3, 3, 50], [2, -3, 3, 50, 5], [2, -3, 3, 50, 5, 0],
 [2, -3, 3, 50, 5, 0, -1], [-3], [-3, 3], [-3, 3, 50], [-3, 3, 50, 5], [-3, 3, 50, 5, 0],
 [-3, 3, 50, 5, 0, -1], [3], [3, 50], [3, 50, 5], [3, 50, 5, 0], [3, 50, 5, 0, -1], [50],
 [50, 5], [50, 5, 0], [50, 5, 0, -1], [5], [5, 0], [5, 0, -1], [0], [0, -1], [-1]]
>>> [sum(j) for j in [L[j:i] for i in range(len(L),0,-1) for j in range(len(L))]]
[56, 54, 57, 54, 4, -1, -1, 57, 55, 58, 55, 5, 0, 0, 57, 55, 58, 55, 5, 0, 0, 52, 50, 53,
 50, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, -1, -3, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0]
>>> # 合并为一行代码:
>>> max(sum(j) for j in [L[j:i] for i in range(len(L),0,-1) for j in range(len(L))])
58
>>> 
>>> # 和最大的子序列为:
>>> l = [L[i:j] for i in range(len(L)) for j in range(i+1,len(L)+1)]
>>> m = max(sum(j) for j in [L[j:i] for i in range(len(L),0,-1) for j in range(len(L))])
>>> [i for i in l if sum(i)==m]
[[3, 50, 5], [3, 50, 5, 0]]
>>> 



4. 根据方程式画出字符图

略:见相关文章《探究“一行代码画爱心”的秘密,去向心爱的人表白吧

5. EXCEL表格列号字串转整数

>>> ExcelCol2Int = lambda s:sum([(ord(n)-64)*26**i for i,n in enumerate(list(s)[::-1])])
>>> ExcelCol2Int('A')
1
>>> ExcelCol2Int('AA')
27
>>> ExcelCol2Int('AX')
50
>>> ExcelCol2Int('CV')
100
>>> ExcelCol2Int('AAA')
703
>>> ExcelCol2Int('XFD')
16384
>>> 



6. 打印Gray格雷码序列

什么是格雷码,什么是卡诺图?不懂的问度娘吧

Gray = lambda n:[(i>>1)^i for i in range(2**n)]
GrayB = lambda n:[bin((i>>1)^i)[2:].rjust(n,'0') for i in range(2**n)]
'''
Gray(0)
[0]
Gray(1)
[0, 1]
Gray(2)
[0, 1, 3, 2]
Gray(3)
[0, 1, 3, 2, 6, 7, 5, 4]
Gray(4)
[0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8]
>>> GrayB(3)    # 把输出排成矩阵,即三变量卡诺图
['000', '001', '011', '010',
 '110', '111', '101', '100']
>>> GrayB(4)    # 把输出排成方阵,即四变量卡诺图
['0000', '0001', '0011', '0010',
 '0110', '0111', '0101', '0100',
 '1100', '1101', '1111', '1110',
 '1010', '1011', '1001', '1000']
'''


注:上面代码中的 (i>>1)^i 可以写成: i^i>>1 或 i^i//2,因为右移或整除的运算级别都比异或要高。验证代码如下:

1. >>> any([(i>>1)^i == i^i>>1 == i^i//2 for i in range(323)])
2. True
3. >>>



另外,观察到Gray()输出的整数序列的规律,就想到用迭代法也能实现,并且只要2行代码:

   # 用迭代法实现:

 

# 用迭代法实现:
def iGray(n):
  if n==0: return [0]
  return iGray(n-1)+[i+2**(n-1) for i in iGray(n-1)[::-1]]






高阶实例


1. 杨辉三角形

方法一:公式递推

>>> def func(i):
  t=L=[1]
  while(i>1):
    i-=1
    t=L+[t[n]+t[n+1] for n in range(len(t)-1)]+L
  return t
>>> func(1)
[1]
>>> func(3)
[1, 2, 1]
>>> func(8)
[1, 7, 21, 35, 35, 21, 7, 1]
>>>
>>> for i in range(1,10):print(func(i))
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
>>>



方法二:组合公式的自定义函数

>>> def Combin(n,i):
    m,t=min(i,n-i),1
    for j in range(0,m):
        t*=(n-j)/(m-j)
    return t
>>> [Combin(8,i) for i in range(9)]
[1, 8.0, 28.0, 55.99999999999999, 70.0, 55.99999999999999, 28.0, 8.0, 1]
>>> [round(Combin(8,i)) for i in range(9)]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
>>> [[round(Combin(j,i)) for i in range(j+1)] for j in range(10)]
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1],
 [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56,
 28, 8, 1], [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]]
>>> 



根据组合公式用阶乘来计算:

C(m,n)=math.factorial(n)//(math.factorial(m)*math.factorial(n-m))  

递归法,虽然没有小数精度的问题,但也有递归次数不能太大即n值有限制的缺点:

>>> def Comb(n,i):
    if i in [0,n]:
        return 1
    elif i==1:
        return n
    else:
        return Comb(n-1,i-1)+Comb(n-1,i)
>>> [Comb(8,i) for i in range(9)]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
>>> print('\n'.join(['\t'.join([str(Comb(j,i)) for i in range(j+1)]) for j in range(10)]))
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10  10  5 1
1 6 15  20  15  6 1
1 7 21  35  35  21  7 1
1 8 28  56  70  56  28  8 1
1 9 36  84  126 126 84  36  9 1
>>> 



方法三:使用现成的库函数

(1). itertools库combinations函数

>>> from itertools import combinations as comb
>>> [[len(list(comb(range(j),i))) for i in range(j+1)] for j in range(10)]
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1],
 [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56,
 28, 8, 1], [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]]
>>> print('\n'.join(['\t'.join([str(len(list(comb(range(j),i)))) for i in range(j+1)]) for j in range(10)]))
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10  10  5 1
1 6 15  20  15  6 1
1 7 21  35  35  21  7 1
1 8 28  56  70  56  28  8 1
1 9 36  84  126 126 84  36  9 1
>>> 

(2). scipy库comb函数

>>> from scipy.special import comb
>>> [[round(comb(j,i)) for i in range(j+1)] for j in range(10)]
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1],
 [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56,
 28, 8, 1], [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]]
>>> print('\n'.join(['\t'.join([str(round(comb(j,i))) for i in range(j+1)]) for j in range(10)]))
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10  10  5 1
1 6 15  20  15  6 1
1 7 21  35  35  21  7 1
1 8 28  56  70  56  28  8 1
1 9 36  84  126 126 84  36  9 1
>>> 





2. 斐波那契数列

(1). 引入自定义函数或lambda表达式:

>>> f=lambda n:n<3 and 1 or f(n-1)+f(n-2)
>>> [f(i) for i in range(1,30)]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181,
 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229]
>>> 


注:这个lambda函数用了递归法,在项数大于40后速度超慢。

另:类似【n<3 and 1 or 2】这种表达式中,逻辑与、或有这样的特性:

  and 两边都对取后面一个表达式, or 两边都对取前面一个表达式

>>> n=5
>>> 1 and n
5
>>> n and 1
1
>>> 0 and n
0
>>> n and 0
0
>>> 1 or n
1
>>> n or 1
5
>>> 0 or n
5
>>> n or 0
5
>>> 


(2). 引入临时推导表达式:

>>> N=50 # 项数=50
>>> f=[1,1]
>>> [f.append(f[n-2]+f[n-1]) for n in range(2,N)]
[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, 
None, None, None]
>>> f
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 
10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 
2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 
165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 
7778742049, 12586269025]
>>> ###合成一行,临时变量接收[None]*n列表###
>>> f=[1,1];t=[f.append(f[n-2]+f[n-1]) for n in range(2,N)]
>>> f
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 
10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 
2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 
165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 
7778742049, 12586269025]
>>>



真的一行代码:

>>> N=50 # 项数=50
>>> t=[(f[n][0], f.append((f[n][1],f[n][0]+f[n][1]))) for f in ([[1,1]],) for n in range(N)]
>>> t
[(1, None), (1, None), (2, None), (3, None), (5, None), (8, None), (13, None), (21, None), 
(34, None), (55, None), (89, None), (144, None), (233, None), (377, None), (610, None), 
(987, None), (1597, None), (2584, None), (4181, None), (6765, None), (10946, None), (17711, 
None), (28657, None), (46368, None), (75025, None), (121393, None), (196418, None), 
(317811, None), (514229, None), (832040, None), (1346269, None), (2178309, None), (3524578, 
None), (5702887, None), (9227465, None), (14930352, None), (24157817, None), (39088169, 
None), (63245986, None), (102334155, None), (165580141, None), (267914296, None), 
(433494437, None), (701408733, None), (1134903170, None), (1836311903, None), (2971215073, 
None), (4807526976, None), (7778742049, None), (12586269025, None)]
>>> [f[0] for f in t]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 
10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 
2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 
165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 
7778742049, 12586269025]
>>> ###合并成一行###
>>> [f[0] for f in [(f[n][0], f.append((f[n][1],f[n][0]+f[n][1]))) for f in ([[1,1]],) for n in range(N)]]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 
10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 
2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 
165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 
7778742049, 12586269025]
>>> 


3. 曼德勃罗集(Mandelbrot Set)分形

>>> print('\n'.join([''.join(['*'if abs((lambda a:lambda z,c,n:a(a,z,c,n))(lambda s,z,c,n:s(s,z*z+c,c,n-1) if n else z)(0,0.02*x+0.05j*y,40))<2 else ' ' for x in range(-78,20)]) for y in range(-20,21)]))
                                                                              *                   
                                                                        **                        
                                                                   ***********                    
                                                                  ************                    
                                                                    *********                     
                                                          *    * ************  * *                
                                                  ****** * *************************** *          
                                                  *************************************** *****   
                                                   *******************************************    
                                             *** ******************************************** *   
                                              **************************************************  
                                           *******************************************************
                    *        *              ***************************************************** 
                   **** ******* *          *******************************************************
                    *****************     ******************************************************* 
                 *********************** *********************************************************
                 *********************** ******************************************************** 
           **** ********************************************************************************  
*******************************************************************************************       
           **** ********************************************************************************  
                 *********************** ******************************************************** 
                 *********************** *********************************************************
                    *****************     ******************************************************* 
                   **** ******* *          *******************************************************
                    *        *              ***************************************************** 
                                           *******************************************************
                                              **************************************************  
                                             *** ******************************************** *   
                                                   *******************************************    
                                                  *************************************** *****   
                                                  ****** * *************************** *          
                                                          *    * ************  * *                
                                                                    *********                     
                                                                  ************                    
                                                                   ***********                    
                                                                        **                        
                                                                              *                   
>>> 



附录


3e6709e37e0147f5b32db4af15ec3aef.png


目录
相关文章
|
4天前
|
Python
探索Python中的列表推导式
【10月更文挑战第38天】本文深入探讨了Python中强大而简洁的编程工具——列表推导式。从基础使用到高级技巧,我们将一步步揭示如何利用这个特性来简化代码、提高效率。你将了解到,列表推导式不仅仅是编码的快捷方式,它还能帮助我们以更加Pythonic的方式思考问题。准备好让你的Python代码变得更加优雅和高效了吗?让我们开始吧!
|
19天前
|
Python
SciPy 教程 之 SciPy 模块列表 13
SciPy教程之SciPy模块列表13:单位类型。常量模块包含多种单位,如公制、二进制(字节)、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例代码展示了如何使用`constants`模块获取零摄氏度对应的开尔文值(273.15)和华氏度与摄氏度的转换系数(0.5556)。
17 1
|
20天前
|
弹性计算 安全 数据处理
Python高手秘籍:列表推导式与Lambda函数的高效应用
列表推导式和Lambda函数是Python中强大的工具。列表推导式允许在一行代码中生成新列表,而Lambda函数则是用于简单操作的匿名函数。通过示例展示了如何使用这些工具进行数据处理和功能实现,包括生成偶数平方、展平二维列表、按长度排序单词等。这些工具在Python编程中具有高度的灵活性和实用性。
|
13天前
|
测试技术 API 数据安全/隐私保护
Python连接到Jira实例、登录、查询、修改和创建bug
通过使用Python和Jira的REST API,可以方便地连接到Jira实例并进行各种操作,包括查询、修改和创建Bug。`jira`库提供了简洁的接口,使得这些操作变得简单易行。无论是自动化测试还是开发工作流的集成,这些方法都可以极大地提高效率和准确性。希望通过本文的介绍,您能够更好地理解和应用这些技术。
54 0
|
17天前
|
Python
SciPy 教程 之 SciPy 模块列表 16
SciPy教程之SciPy模块列表16 - 单位类型。常量模块包含多种单位,如公制、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例代码展示了力学单位的使用,如牛顿、磅力和千克力等。
15 0
|
18天前
|
JavaScript Python
SciPy 教程 之 SciPy 模块列表 15
SciPy 教程之 SciPy 模块列表 15 - 功率单位。常量模块包含多种单位,如公制、质量、时间等。功率单位中,1 瓦特定义为 1 焦耳/秒,表示每秒转换或耗散的能量速率。示例代码展示了如何使用 `constants` 模块获取马力值(745.6998715822701)。
15 0
|
18天前
|
JavaScript Python
SciPy 教程 之 SciPy 模块列表 15
SciPy教程之SciPy模块列表15:单位类型。常量模块包含多种单位,如公制、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。功率单位以瓦特(W)表示,1W=1J/s。示例代码展示了如何使用`constants`模块获取马力(hp)的值,结果为745.6998715822701。
16 0
|
18天前
|
C语言 Python
探索Python中的列表推导式:简洁而强大的工具
【10月更文挑战第24天】在Python编程的世界中,追求代码的简洁性和可读性是永恒的主题。列表推导式(List Comprehensions)作为Python语言的一个特色功能,提供了一种优雅且高效的方法来创建和处理列表。本文将深入探讨列表推导式的使用场景、语法结构以及如何通过它简化日常编程任务。
|
19天前
|
Python
SciPy 教程 之 SciPy 模块列表 13
SciPy 教程之 SciPy 模块列表 13 - 单位类型。常量模块包含多种单位:公制、二进制(字节)、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例:`constants.zero_Celsius` 返回 273.15 开尔文,`constants.degree_Fahrenheit` 返回 0.5555555555555556。
14 0
|
20天前
|
Python
SciPy 教程 之 SciPy 模块列表 11
SciPy教程之SciPy模块列表11:单位类型。常量模块包含公制单位、质量单位、角度换算、时间单位、长度单位、压强单位、体积单位、速度单位、温度单位、能量单位、功率单位、力学单位等。体积单位示例展示了不同体积单位的换算,如升、加仑、流体盎司、桶等。
15 0