免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5217 | 回复: 15

一行代码打印质数表,这两个lambda函数要怎么整合 [复制链接]

论坛徽章:
0
发表于 2013-06-01 01:02 |显示全部楼层
本帖最后由 pallas2k 于 2013-06-01 01:28 编辑

看了一个关于python里尽量少用for循环语句的帖子,很受启发,试着用函数式编程写了个求 1-100内质数的小段,代码如下,python 3.3

from functools import reduce

IsPri = lambda priList,a: all( map( lambda i: a%i, priList) )

def GenList(x,y):
    x.append(y) if IsPri(x,y) else 0
    return x

print ( reduce(GenList, range(3,100), [2]) )

现在我想知道,有什么法子能把GenList和IsPri 这两个函数定义取消,变成两个 lambda函数 整合到最后一个 reduce 里去,从而实现,一行代码打印质数表呢
我发现要点在于 x.append(y) 这个不是表达式,返回值不是x 以及  V1 if con else V2 条件表达式里 怎么使用 lambda函数

论坛徽章:
0
发表于 2013-06-01 01:10 |显示全部楼层
本帖最后由 pallas2k 于 2013-06-01 01:29 编辑

好吧 后一个难点已经解决了,代码变成了这个样子

from functools import reduce

def GenList(x,y):
    x.append(y) if (lambda priList,a: all( map( lambda i: a%i, priList) ) )(x,y) else 0
    return x

print ( reduce(GenList, range(3,100), [2]) )

请版上的达人指点,怎么把那个GenList改造成lambda函数嵌到最后一行里去。多谢了

论坛徽章:
0
发表于 2013-06-01 10:58 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-06-01 11:00 编辑

回复 1# pallas2k

你说的"尽量少用for”,也有个限度,那就是“可读为王”

请尝试import this

改造后可读行太差的话,还是算了。

如果你有兴趣,可以搜索“混乱代码大赛”,参考:http://www.guokr.com/post/364973/

论坛徽章:
0
发表于 2013-06-01 11:32 |显示全部楼层
  1. reduce(lambda x,y:x if not (x.append(y) if (lambda x,y:all(map(lambda i:y%i,x)))(x,y) else 0) else 0  \
  2.               , range(3,100), [2])
复制代码
可以正确运行,我试了一下。
然而仍然十分不推荐这样写代码,可读性太差了,不是Python追求的风格

论坛徽章:
0
发表于 2013-06-01 11:33 |显示全部楼层
解释一下,因为list.appnd总是返回None,加一个not就是True,所以就可以返回插入新数之后的序列了

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
发表于 2013-06-01 16:32 |显示全部楼层
本帖最后由 ssfjhh 于 2013-06-01 17:05 编辑

楼主要的是这个结果吗?
判断某个数是不是素数。
  1. >>> p = lambda x: x>1 and all(map(lambda s:x%s, range(2,int(x**.5+1))))
  2. >>> p(2)
  3. True
  4. >>> p(4)
  5. False
  6. >>> p(9)
  7. False
  8. >>> p(10)
  9. False
  10. >>> p(11)
  11. True
  12. >>>
复制代码

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
发表于 2013-06-01 16:59 |显示全部楼层
本帖最后由 ssfjhh 于 2013-06-01 17:01 编辑

如果楼上的结果不是楼主想要的,那这个一定是了。
  1. tuple(filter(lambda x: x>1 and all(map((lambda s: x%s), range(2,int(x**.5+1)))), range(1000)))
复制代码
这行代码可以将1000以内的素数以元组的形式返回,可读性就惨不忍睹了。


另外提醒楼主,python3是没有reduce这个内置函数的。

论坛徽章:
0
发表于 2013-06-01 21:14 |显示全部楼层
嗯 谢谢楼上各位,尤其是4楼的达人,真是给了极大的启发,一通百通啊。说实话,实际运用我肯定也不用这种代码,因为才隔了一晚,直接读那一行我也已经有点看不懂了。其实主要还是想尝试下lambda函数的限制在哪里,和如何设法绕过。免得练习写lambda老是写报错,而不知道怎么修正。

以前我用python也是当C那样用,map、filter、reduce完全不触碰的,写出来的完全是python语法的C程序而已。但是最近看了篇文章,突然开悟了。那里面说到,其实一般for循环,就做三种事,变换一组值到另一组,对一组值过滤并操作,对一个初始状态按照一个列连续变换,这正是那三个函数的功能,而且使用他们,实现了运算和遍历的分离。逻辑更清晰,所以在试着按这个思路重构以前的程序,感觉以前python简直是白学了。
现在看,如果按帖子介绍的完全放弃 for if 这两个语句,看起来也可以,只是大概括弧就会象lisp一样多吧。这也难怪以前我用AutoCAD的VLisp感觉非常不舒服,我是把Lisp当C来用呢,^_^,我要回头去学一下Lisp。

论坛徽章:
0
发表于 2013-06-01 21:25 |显示全部楼层
另外还有个疑问
IsPri = lambda priList,a: all( map( lambda i: a%i, priList) )

这个函数,是用现有质数表priList判断一个数a是否是质数的,那个map对priList的所有成员都遍历了,而其实我们知道,只要有一个 a%i==0 这个遍历就可以中止了
在for - if 结构中,这是很容易做到的,但函数式的话,有什么便捷方法呢

就是说,在用map对列表遍历运算的同时,可以中途按条件打断。
譬如现在有个要求,生成不大于N的2的次方,形如[2,4,8,16,32,64,……] ,且最后一个值小于N。 先生成全表再删除的方式弱爆啦。

论坛徽章:
0
发表于 2013-06-01 21:26 |显示全部楼层
回复 7# ssfjhh


    所以他才import了嘛
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP