python 实例详解map()函数、lambda函数、二进制移位--生成和2的次方有关的矩阵
一、map()函数
1、map() 会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
map(func,iterables)
2、其中iterables是迭代函数的意思,也就是要执行function的序列。在python 3x中,map函数生成的map() 生成的是迭代器不是list,直接运行会提示“<map at 0x1fb2382ce10>”一类的信息,如下第一行代码;如果要生成list,可以在map前加上list,即list(map()),如下第二行代码。
map(sum,([1,2],[3,4])) list(map(sum,([1,2],[3,4])))
3、以下是更多map()的使用实例。
>>>def square(x) : # 计算平方数 ... return x ** 2 ... >>> map(square, [1,2,3,4,5]) # 计算列表各个元素的平方 [1, 4, 9, 16, 25] >>> map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数 [1, 4, 9, 16, 25] # 提供了两个列表,对相同位置的列表数据进行相加 >>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]) [3, 7, 11, 15, 19]
总之,在需要对序列的每一个元素进行操作时,map()是个不错的选择。
二、lambda函数
Lambda函数又称匿名函数,匿名函数就是没有名字的函数,在实际运用中主要用于只使用一次,功能较为简单的函数。
lambda argument_list: expression
argument_list即参数列表,expression指函数的具体表达。如最简单的lambda函数。
>>> lambda x :x+1 <function <lambda> at 0x000001E2703B9D90> #因为lambda是匿名函数,如果单独运行它的话要给它一个名字。 >>> add = lambda x :x+1 >>> add(2) 3
关于具体的使用方法和场景,可以参见以下博客:
https://www.cnblogs.com/huangbiquan/p/8030298.html
三、二进制移位
“>>‘”和“<<”都是位运算,对二进制数进行移位操作。
①“<<” 是左移,末位补0,类比十进制数在末尾添0相当于原数乘以10,
x<<1是将x的二进制表示左移一位,相当于原数x乘2。
整数4在二进制下是100,4<<1左移1位变成1000(二进制),结果是8。
>>> 2<<1 4 >>> 4<<1 8
②“>>‘”是右移,右移1位相当于除以2。
③>>=和<<=,就是对变量进行位运算移位之后的结果再赋值给原来的变量,可以类比赋值运算符+=和-=可以理解。
比如x>>=2, 就是把变量x右移2位,再保留x操作后的值。
>>> x = 4 >>> x>>=2 >>> x 1
二进制移位在涉及2的次方的运算时可以简化代码,非常方便。
四、实例讲解
(一)解析需求
实现一个函数make_mat(n),创建类似如下的矩阵:
[[1, 2, 4, 8, 4, 2, 1],
[2, 4, 8, 16, 8, 4, 2],
[4, 8, 16, 32, 16, 8, 4],
[8, 16, 32, 64, 32, 16, 8],
[4, 8, 16, 32, 16, 8, 4],
[2, 4, 8, 16, 8, 4, 2],
[1, 2, 4, 8, 4, 2, 1],]
参数:n
返回值:一个长度为n的列表,这个列表里面的元素都是长度为n的列表
(相当于n*n的一个二维表),规律和2的次方有关(自己找吧)。
上面给出的例子是调用make_mat(7)的结果。
解析:
从题目中可以看出,要求实现给定一个n值,输出一个矩阵,其中矩阵内有n个列表,每个列表有n个元素,每个元素与前一个存在2次方关系。
(二)解答方法
1、方法一:
算法NS图如下:
源码如下:
def make_mat(n): l=n//2 #l是作为分界点,将ii,jj与其比较,判断是应该乘以还是除以2. ls=[] #输出列表首先为空 for i in range(n): ls.append([]) #对于给定的n,有n个子列表。每循环一次,添加一个子列表。 for j in range(n): ii,jj=i,j if i>=l: ii=n-1-i if j>=l: jj=n-1-j #如果i,j小于l,则乘以二,即二进制左移一位 ls[i].append(1<<(ii+jj)) return ls make_mat(7) >>>[[1, 2, 4, 8, 4, 2, 1], [2, 4, 8, 16, 8, 4, 2], [4, 8, 16, 32, 16, 8, 4], [8, 16, 32, 64, 32, 16, 8], [4, 8, 16, 32, 16, 8, 4], [2, 4, 8, 16, 8, 4, 2], [1, 2, 4, 8, 4, 2, 1]]
2、方法二:用map()和lambda将方法一简化
源码如下:
def make_mat(n): return [[1<<sum(map(lambda x:int((n-1)/2-abs(x-(n-1)/2)),(i,j))) \ for j in range(n)] 2a81e for i in range(n)] make_mat(7) >>>[[1, 2, 4, 8, 4, 2, 1], [2, 4, 8, 16, 8, 4, 2], [4, 8, 16, 32, 16, 8, 4], [8, 16, 32, 64, 32, 16, 8], [4, 8, 16, 32, 16, 8, 4], [2, 4, 8, 16, 8, 4, 2], [1, 2, 4, 8, 4, 2, 1]]
拆分理解如下:
abs( )表示求绝对值,即求 x-(n-1)/2 的绝对值,以绝对值的形式,可以实现方法一中判断是应该乘以还是除以2的功能。
lambda函数的功能是,对于每一个x,求 int((n-1)/2-abs(x-(n-1)/2)的值。
lambda x:int((n-1)/2-abs(x-(n-1)/2))
map( )可以对(i,j)这个数组的每个元素进行lambda操作,也就是对i和j分别进行lambda操作,返回的是迭代器,不能直接输出。
map(lambda x:int((n-1)/2-abs(x-(n-1)/2)),(i,j))
加上sum( )后,功能是在map返回的迭代器中每个数进行相乘,其等价于sum(list(map()))。
for j in range(n) 和for i in range(n)限定了循环的范围。
3、方法三:用传统的函数方法,不使用二进制
其实这个方法是我在没看到标准答案时候写出来的,相比标准答案实在有些繁琐,不过也放上来吧,不知道二进制位移和map函数的朋友,可能可以先从我这个思路入手:根据给定的n,先生成第一个子列表,再对第一个子列表进行操作生成后续的子列表。
源码如下:
import numpy as np def get_first(n): #根据n得到第一个子列表 list_o = [] num = 1 list_o.append(num) for i in range(int((n+1)/2) -1): num = num * 2 list_o.append(num) #生成递增的那部分元素,并添加到列表中 for i in range(int(n/2)-1,-1,-1): list_o.append(list_o[i]) #生成递减的那部分元素,并添加到列表中 return list_o def get_all(ls,n,out): a = np.array(ls) #把列表转换为array数组,方便用每个元素乘以或除以2 out.append(list(a.astype(np.int16))) #array数组默认是浮点数,用array.astype(np.int16)转换为整数 for i in range(int((n+1)/2) -1): #原理和获取第一个子列表是一样的。 a = a *2 #print(a) out.append(list(a.astype(np.int16))) for i in range(int(n/2)-1,-1,-1): out.append(out[i]) return out def make_mat(n): n = n out = [] print(get_all(get_first(n),n,out)) make_mat(7) >>>[[1, 2, 4, 8, 4, 2, 1], [2, 4, 8, 16, 8, 4, 2], [4, 8, 16, 32, 16, 8, 4], [8, 16, 32, 64, 32, 16, 8], [4, 8, 16, 32, 16, 8, 4], [2, 4, 8, 16, 8, 4, 2], [1, 2, 4, 8, 4, 2, 1]]
为了改进用户体验,添加了获取输入和输出的提示词以及捕捉异常,将主函数改成如下代码:
def make_mat(): while True: get_num = input("请输入n的值,n为正整数(按e结束进程):") try: if get_num == "e": break elif isinstance (eval(get_num),int) and (eval(get_num)>1): n = eval(get_num) out = [] print("得到的结果是:\n{}".format(get_all(get_first(n),n,out))) elif get_num == "1": out = [[1]] print("得到的结果是:\n{}".format(out)) else: print("请输入正确的n值。") except: print("请输入正确的n值。")
其中 isinstance (x,A)是对x进行类型判断,如果x属于A类型,则返回True,否则返回False。
>>> isinstance(121,int) True >>> isinstance(123,str) False
写在最后:
推荐一个画NS图的工具,DiagramDesignerSetup1.28,修改方便,简单易学。
中文版下载 http://pan.baidu.com/s/1eSsFURS
- Python使用QRCode模块生成二维码实例详解
- 【Python】3.函数混淆知识点及实例详解
- python2,3中内建函数map,reduce,filter,sorted配合lambda
- 【python】详解lambda匿名函数以及结合map、reduce、filter、sorted等使用
- Python基础之函数用法实例详解
- python几个特别函数map filter reduce lambda
- 详解C++调用Python脚本中的函数的实例代码
- python的lambda表达式 内建函数filter map reduce
- 详解Python匿名函数(lambda函数)
- 【matlab】函数meshgrid的用法详解(生成网格矩阵)和ndgrid的区别及用法
- Python入门之三角函数tan()函数实例详解
- python的map函数和lambda函数
- python 迭代器和iter()函数详解及实例
- python特殊函数之lambda和map
- [Python] 函数lambda(), filter(), map(), reduce()
- Python高级特性: 函数编程 lambda, filter,map,reduce
- python 的 map 函数 和 lambda函数
- 详解python中的lambda函数
- python map函数用法详解
- python中的map()函数详解