Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4560837
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: Python/Ruby

2011-12-23 02:00:05

文章来源:http://www.cnblogs.com/huxi/archive/2010/12/19/1910425.html

这个问题来源于一次回答问题的过程。论坛上有新手提了一个问题,问题是这样的:

python re 有没有 php里 preg_replace 这样的函数?
我想实现两组数对调的效果  ,比如  1对5 2对6  3对7 4对8
php里只需要
$a=array('1','2','3','4');
$b=array('5','6','7','8');
$strnow='1234';
$new=preg_replace($a,$b,$strnow);
new就是5678
但是re.sub肯定是不能这么批量实现的,怎么解决呢?

相信这个问题对熟悉Python的朋友来说一定不难,虽然论坛上人气不高,还是有了好几个回复。比如某位朋友回复:

1
2
3
4
5
6
7
def root(x,y='',dct={'1':'5','2':'6','3':'7','4':'8'}):
    for i in x:
        if i in dct:
            y+=dct[i]
        else:
            y+=i
    return y

这段代码其实可以运行并且结果是对的,但一眼看上去总觉得有些别扭。于是我跟帖给了3个答案做这件事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = ['1', '2', '3', '4']
b = ['5', '6', '7', '8']
s = '1234'
 
# method1
import re
print re.sub('.', lambda m: dict(zip(a, b)).get(m.group(), m.group()), s)
 
# method2
print ''.join(dict(zip(a, b)).get(c, c) for c in s)
 
#method3
import string
print s.translate(string.maketrans(''.join(a), ''.join(b)))

这时候一位朋友提到:

大家都迷上了使用一行的代码来解决问题,看起来又复杂又酷,这些代码如果让新人看到得琢磨一阵子了

这句话的前半部分确实有一定的道理。我们在论坛上遇到类似这样的问题帖时,经常会看到跟帖者像是在竞赛一样用各种语言尽可能短地给出答案。我给的前两个答案也有同样的毛病,实现确实带有一些炫耀性质,实际上是应该这样写的:

1
2
3
4
5
6
7
8
9
10
11
d = dict(zip(a, b))
 
# method1
import re
def repr(m):
    c = m.group()
    return d.get(c, c)
print re.sub('.', repr, s)
 
# method2
print ''.join(d.get(c, c) for c in s)

但如果说只因为酷就要避开,这似乎又走入了另一个极端。再回头看看第一段类似C的代码吧,如果我们的代码都这样写,为什么我们还要用Python呢?

有大牛说过,一门好的编程语言,能改变你的编程思维,如果你觉得一门语言没有做到这一点,那么就不值得花时间去学习这门语言(大意如此,记忆力不佳 ^^)。体现在C to Python上的话,内置的列表解析和大量的封装代码逻辑的方法(Python有一个文档详细介绍了这些,标题很酷叫做函数式编程指南)完全可以颠覆对程 序源代码的认识。试想,如果用一个列表生成另一个列表,写成这样:

1
2
3
l2 = []
for i in l1:
    l2.append(i)

与写成这样:

1
l2 = [i for i in l1]

哪个会好一些呢?可能对新人来说,上面那样更符合他们固有的逻辑,但我想这并不足以阻挡我们使用列表解析,更不应该因此而逃避内置的zip map reduce等等方法,这些方法都有现成的文档可查,为什么我们要放弃他们,使用一层一层的for循环呢?我在第一次看到Python这么精妙的代码时, 很是惊叹。如果要放弃这些功能,那是多么令人郁闷的事情。

别因为cool就抗拒,别忘了酷也是Python的特性之一。


阅读(1184) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~