python中map函数返回值类型_新手请教python问题,就是说像map,zip,filter这些函数都返回单次迭代器。?...

对于map来说, 真的要看情况的。

某人在学习Python函数的时候, 介绍map()函数的使用:

def sqr(x):

return x ** 2

a = [1, 2, 3]

print map(sqr, a)

这个map函数是python的内嵌的函数, 那么如何手写一个自己的map函数, 实现内嵌map函数一模一样的功能呢?

第一式: 不固定参数

Python内嵌的map函数允许不固定参数, 如下图所示, map第一个参数是一个函数, 剩余的不固定参数只要iterative类型就可以。 譬如,下面可以是元组和数组。

def add(x, y):

return x + y

a = (2, 3, 4)

b = [10, 5, 3]

print map(add, a, b)

那么如何实现这个不固定参数的读取呢? Python给了*var的形式,可以接受任意参数。 某人根据map的功能进行设计, 先将之后的参数按行拼接成参数, 然后调用函数,得到返回值。

于是,某人实现了如下函数:

def my_map(func, *lst):

res = []

m = len(lst)

n = len(lst[0])

for i in range(n):

args = []

for j in range(m):

args.append(lst[j][i])

res.append(func(*args))

return res

跑一下, 杠杠的!和map()结果一致。

但是, 这个是不是内嵌map的全部实现呢?

第二式: 对齐Iterator,返回默认值

所谓天大差别, 不过一横, 就算差了一点, 任然差别太大。 所以在比较my_map和内嵌的map的时候,是不是还要边界检查。 前面测试了相同长度的数组的map, 对于不同长度的数组的map呢?

a = (2, 3, 4)

b = [10, 5, 3]

print map(lambda x,y: '{}~{}'.format(x,y), a, b+[0])

print my_map(lambda x,y: '{}~{}'.format(x,y), a, b+[0])

可以上面结构看到, 内嵌的map会按最大长度自动补齐。

那么一种实现,就是找到数据里面最长的, 将所有不够长的补齐None值,之后再调用my_map()

另外一种,我就是利用iterator到结束之后, 默认返回None值。默认的next()函数的第二个参数,可以是返回的默认值。

def my_map2(func, *lst):

res = []

its = [iter(it) for it in lst]

ln = max([len(it)for it in lst])

while ln > 0:

args = [next(it,None) for it in its]

res.append(func(*args))

ln -= 1

return res

a = (2, 3, 4)

b = [10, 5, 3]

print map(lambda x,y: '{}~{}'.format(x,y), a, b+[0])

print my_map2(lambda x,y: '{}~{}'.format(x,y), a, b+[0])

效果不错, 那么是不是就搞定了呢?

第三式: Python 2,3兼容,内部类型变换

是不是上面实现的my_map2(),就是一个python2和python3下都和map函数一致呢? 前面,我们在使用print函数的时候, 没有使用括号, 那么明显是在Python2的环境下面, 那么对于Python3环境下呢?在Python3下测试一下吧:

我们发现打印了是一个map object。嘿, 内嵌map函数的实现, 在Python2和Python3中似乎很不一样。 如果我们试图通过subscribe[]来访问的的时候,发现这个map并不可以通过index来访问。

那么基本判断就是一个iterative的对象。 但是如何打印具体内容出来看呢? 最好是通过Python的内部变量之间转换进行list()

这样, 那么我们再次调用非对齐的map来测试:

print (list(map(lambda x,y: '{}~{}'.format(x,y), a, b+[0])))

我们发现在Python3里面不再按照最长的iteration来进行对齐了, 而是按照最短的来对齐。 因此, 我们可以把最长换成最短来模拟Python3中的map。

def my_map3(func, *lst):

res = []

its = [iter(it) for it in lst]

ln = min([len(it)for it in lst])

while ln > 0:

args = [next(it,None) for it in its]

res.append(func(*args))

ln -= 1

return res

是不是my_map3()在Python3中,就是最好的模拟呢?

第四式: 对齐Iterator,返回默认值

但是毕竟Python3中返回的是一个iterator,一个差异就是, 我们返回一个数组(数组可以通过subscribe[]访问), 我们知道iterator本身,可以通过generator来进行简化, 并且这种lazy实现, 会提高调用效率。 这时候伟大的yield关键词上场了。

一般来说,在Python中, 如何用好yield关键词和decorator功能,都会极大提高工作效率的,也是反应一个人Python功底的东东。

def my_map4(func, *lst):

its = [iter(it) for it in lst]

ln = min([len(it)for it in lst])

while ln > 0:

args = [next(it,None) for it in its]

yield func(*args)

ln -= 1

至此 , 我们可以打印出来,看my_map4返回的也是一个iterative object,这个generator object和map object有着异曲同工之妙。 另外再通过list进行内部变量转化,看到它实现的功能也一致。

至此, 某人听完第三式和第四式的实现, 对Python大大失去兴趣,坑太多! ! !

小结:

本人设计的一个面试题,并且自我回答,通过对Python2和Python3中map函数的测试, 试图自己实现这个内嵌函数, 经验有限,希望大家对map有更为深入的了解,尤其Python2和Python3中实现的巨大差异。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值