http://blog.sciencenet.cn/home.php?mod=space&uid=404069&do=blog&id=297132
(根据我在博客园上连载的四篇文章整理,见http://yanxy.cnblogs.com/,转载请注明出处)

近两天内的目标是在我博的每个栏目发一篇文章,先都占个坑再说,空着不好看:) 《程序设计》这个栏目里,就从我刚开始学的Python开始吧。

一、引言
Python是一种简单却又强大的语言,我觉得它很适合非专业程序员(特别是科研人员)使用。比如作一些科学计算、数据处理工作等,Python简单的语法和丰富的第三方库可以有效帮助我们提高工作效率。
本文并不主要介绍Python编程的语法,或Python怎么安装、运行、调试等,有兴趣可以到科学网潘超的Blog去看看,那里有一些不错的入门资源。整理这篇文章的主要目的还是想介绍下我学、用Python的一些体会,希望能为大家提供借鉴。我学Python已经有十多天了,现在已经初步掌握了Python。我认为好的学习方法不光是看书或上网查资料,最好是能结合一个实际的例子一点点去深入,这样掌握起来会更快更牢。我在写了“Hello World”之后,第一个正式编的程序就是下面这个复制代码时去除行号的小工具。

二、分析与设计
现在很多专业计算机技术网站提供的各种源代码前,很多会带有数字行号。我们将这些代码复制下来运行前,要一行一行的去删除前面的代码,即浪费时间又容易出错。如果有一个程序能快速、正确的去除掉代码前的行号,无疑可以节省我们的很多时间(当然我写这个程序花了大概有10几个小时,不过正所谓“磨刀不误砍柴工”嘛:)。
网上代码前的行号排列大都比较有规律,多数采取如下形式:
1. abc
2. def
………………
1 abc
2 def
………………
以及[1]、1:、(1)等。
因此,要去除行号,首先就是要查找到每行的开头数字及前后分割符号,然后替换掉他们。根据这个思路,很容易写出如下的基本程序框架:
第1步:读取全部n行代码到一个字符串,然后将其转换为包含n个子字符串的数组(或列表);
第2步:对于每一个子字符串,从左至右开始查找每个字符,如果找到一个或多个连续的、可转换为整数的字符,就删除其左侧(包含数字自身位置)的全部字符,并用剩余部分生成一个新字符串。
第3步:如果新字符串左侧有空白或:.])等分割符号,就去除掉它们,再用剩余部分生成一个新字符串。
第4步:将所有处理过的字符串顺序连接起来,得到一个字符串,返回处理行号后的源代码。

三、初步的实现——字符串替换
由于Python语言提供了良好的字符串操作功能,因此很快可以写出一个初步的版本:
#代码1

# -*- coding: utf-8 -*-

def CutLineNum(inStr): #用def关键字声明函数,注意后边加冒号     multiStr = inStr.splitlines(1) #将多行文本拆分为文本列表     outStr = u''     for singleStr in multiStr: #循环用for in的结构,后边也加冒号         singleStr = singleStr.lstrip() #去除左侧空白         i=0 #迭代算子         for charStr in singleStr: #从左至右循环查找字符             if charStr.isdigit():#如果判断是数字类型                 i += 1 #迭代算子加1             elif i>0: #找到了一个非数字字符,而且前边已有数字字符                 singleStr = singleStr[i:] #返回从该位置起的剩余字符                 break #跳出循环             else: #如果都没有,说明是空行                 break #跳出循环         outStr += singleStr #将所有行组成完整代码     return outStr #返回
(注意,# -*- coding: utf-8 -*-是使用utf-8编码,可以支持中文字符)
以上代码实现了基本程序框架中的1-3步,第4步由于情况较复杂(有的行号后有分割符,有的没有,而且空格数量也不一样),所以暂时用以下函数手工处理:
#代码2

# -*- coding: utf-8 -*-

def CutLeftChar(inStr):     outStr = u''     multiStr = inStr.splitlines(1)     for singleStr in multiStr:         singleStr = singleStr[1:]         outStr += singleStr     return outStr
这样虽然苯拙一点,但至少解决了问题。
四、进一步优化——正则表达式替换

正则表达式(Regular Expression,简称Regex),是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。关于Python中正则的入门材料可以参考《正则表达式30分钟入门教程》, (不过我觉得30分钟掌握正则表达式还是有困难的,为掌握它我还专门买了一本《精通正则表达式》)。正则表达式是一种处理文本的强大工具,删除代码行号对于它来讲是小菜一叠。下面用正则表达式改写代码1和2,如下:

#代码3
import re #导入Python的正则表达式模块
def CutLineNum (inStr):
    multiStr = inStr.splitlines(1)     outStr = u''
p = re.compile(r'\D*\d+\s?[.|:|\]|\)]?\s?') #编译正则表达式     for singleLine in multiLine:         outStr += p.sub( '', singleLine,count = 1 ) #用空字符替换每行的第一个匹配上述正则表达式的字符串     return outStr  #返回累加后的字符串
 
以上代码中的咖色部分就是一个Regex,它的含义是:0或多个非数字字符 + 至少1个数字字符 + 0或1个空白字符 + 0或1个分隔符(包括点、冒号、右圆/方括号,可添加其他分隔符) + 0或1个空白字符。
以上Regex符合大多数代码前行号的规则,删除行号就是用空字符替换掉每行代码中第一个匹配该Regex的字符串(注意只能是第一个,因为程序里可能会存在abc1.open等情况,如果全部匹配就会误删代码)。
五、继续优化——采用函数编程
代码3看起来还不够简洁,没关系,Python是一种“准”函数编程(Functional Programming,FP)语言,做这种简化代码的事情最拿手。在这里,我用到了两种函数编程手段——匿名函数(lambda)和一种高阶函数(map),将代码简化至一行,如下:
#代码4
import re #导入Python的正则表达式模块
outStr = ''.join(map(lambda x:re.compile(r'\D*\d+\s?[.|:|\]|\)]?\s?').sub( '', x,count = 1 ),inStr.splitlines(1))))
这样代码就只优化到了一行了,是不是很简洁呢?当然代码的可读性受到一定影响。所以函数编程不能滥用。(滥用的例子可以见我的文章《学习Python列表内涵:一行代码搞定双倍超立方数计算》)。函数编程是个稍微复杂点的问题,我觉得掌握与否均可,所以就不很详细地去解释上述代码了。如果对Python的函数编程感兴趣,可以参考《可爱的 Python:Python 中的函数编程》,很不错的一篇文章。
六、完整的程序——添加I/O
完整的程序肯定少不了输入输出功能。对于这个去除复制代码行号的小工具,我想到的输入输出方式一共有三种:
1、文件方式
将复制的代码存为一个文本文件,然后用程序读取它,去掉行号后在写回文件。这种方法应该说是最不方便的,可以算一下自己需要点多少下鼠标……麻烦,所以我没有实现它。关于Python的文件操作内容,网上有很多资料,可以搜索一下。
2、窗口方式
将复制的代码粘贴到一个窗体的文本框里,然后点击按钮去除行号,再从文本框里把处理后的代码复制出来。这是比较常规的做法,我分别用wxPython和PyQt4实现了这项功能,源代码见http://www.cnblogs.com/。由于GUI编程是个比较复杂的问题,我就不详细展开了,以后有时间再写。
3、剪贴板方式
复制代码到剪贴板后,启动处理行号程序,直接处理剪贴板内的文本,然后再复制到其他地方。这是最方便的一种方法,而且由于不用构建GUI,代码量也会很少。见下边:

#代码5
# -*- coding: utf-8 -*-

 import win32clipboard as c #import包的时候,如果包名太长,可以用as起一个别名import win32con as w #以上两个包都是专门针对windows平台的,注意import re

 c.OpenClipboard() #打开剪贴板strList = c.GetClipboardData(w.CF_TEXT).splitlines(1) #读取剪贴板内容到一个字符列表c.EmptyClipboard() #清空剪贴板c.SetClipboardData(w.CF_TEXT, ''.join(map(lambda x:re.compile \     (r'\D*\d+\s?[.|:|\]|\)]?\s?').sub( '', x,count = 1 ),strList )))      #将去处行号后的字符写回剪贴板,此处用到代码3c.CloseClipboard() #关闭剪贴板
七、总结
以上就是我初学Python作的第一个程序,虽然很简单,但在编写这个程序的过程中,我学习到了:
1、Python的基本语法、类型与逻辑控制
2、Python的函数定以及函数编程方法
3、Python的图形用户界面设计(GUI)
4、正则表达式及其在Python中的应用
短时间内就可以学会这么多内容,足以说明Python的简单易学,你也应该能体会到Python的强大吧。此外,在完成这个程序的过程中,我所用到的基本思路是:
1、由粗到细
先根据功能要求实现程序逻辑框架,然后用你所掌握的最基本方法实现初步版本,先让程序能用。在此基础上,再去看是否有继续优化的可能(从代码简洁性或效率两方面),逐步细化,这时候才是提高的过程。
2、自内而外
先实现核心算法,再添加外围功能(I/O,GUI等)。有些编程初学者热衷于用IDE去拖拉控件、美化界面等(当然这项工作也是必要的),没有把更多精力集中到核心算法中去,这样不利于真正学好一门语言。
当然这个程序还有很多需要完善的地方,欢迎提出你的意见或建议。

如果需要了解更多关于Python的内容,可访问啄木鸟社区的《Python 资源索引》。

本文引用地址:http://blog.sciencenet.cn/home.php?mod=space&uid=404069&do=blog&id=297132

转载于:https://www.cnblogs.com/swjm119/archive/2012/01/18/2325280.html

第一个python去掉行号相关推荐

  1. python去掉每行前面_第一个python去掉行号

    (根据我在博客园上连载的四篇文章整理,见http://yanxy.cnblogs.com/,转载请注明出处)近两天内的目标是在我博的每个栏目发一篇文章,先都占个坑再说,空着不好看:) <程序设计 ...

  2. 自己写的python软件可以在哪发布-如何发布一个Python命令行工具

    本文简介 上次写的一个终端里面斗鱼TV弹幕Python版本和Ruby版本,并且发布到PIP和RubyGems上面.在发布PIP包的时候,居然Google不到一篇可以非常好的讲解这个流程的文章.于是整理 ...

  3. java 反编译 行号对齐 decompiler如何去掉行号

    java 反编译 行号对齐 decompiler如何去掉行号 转载于:https://www.cnblogs.com/zhujiabin/p/5597127.html

  4. 如何在R代码中找到一个值的行号

    如何在R代码中找到一个值的行号? 例如: 在以下一组值中,如何在第4列中找到特定值的行号? 如何使用R代码命令找到列4中的值"1578"的行号. > mydata_2sex ...

  5. python统计行号_如何使用Python脚本分析CPU使用情况的?

    用以分析Python中CPU使用情况.CPU分析是通过分析CPU执行代码的方式来测量代码的性能,以此找到代码中的不妥之处,然后处理它们. 接下来我们将看看如何跟踪Python脚本使用时CPU使用情况, ...

  6. python统计行号_利用Python进行数据分析(第三篇上)

    上一篇文章我记录了自己在入门 Python 学习的一些基础内容以及实际操作代码时所碰到的一些问题. 这篇我将会记录我在学习和运用 Python 进行数据分析的过程: 介绍 Numpy 和 Pandas ...

  7. python获取行号_在python中获取当前位置所在的行号和函数名

    python中没办法直接取得当前的行号和函数名.这是有人在论坛里提出的问题,底下一群人只是在猜测python为什么不像__file__一样提供__line__和__func__,但是却最终也没有找到解 ...

  8. python显示行号代码_jupyter notebook实现显示行号

    Jupyter Notebook默认不显示行号,可是当我们代码报错时,发现会显示自己多少行出现错误. eg: 这时候我们总不能一行行去数吧,因此,为了方便我们调试排错.我们需要让jupyter not ...

  9. pandas如何获取某一个元素的行号,也就是索引值

    之前一直困扰了我很长时间.就是如何获得某一个数据表里面,符合一定条件的值的索引,或者行号. 今天终于可以做出来了. 比如: 有一个数据, 想要找到这个数据里面,是2018年的呢,怎么办,可以写for循 ...

最新文章

  1. MATLAB 无约束一维极值问题
  2. HTTP状态码和编程
  3. Linux系统常用命令速查手册,建议打印
  4. python中函数和方法的区别
  5. mac 雪豹 10.6 五国
  6. java正则表达式用法示例_Java正则表达式教程及示例
  7. [vue] vue的:class和:style有几种表示方式?
  8. c++ main函数调用 类中的枚举_为什么 Java 的 main 方法必须是 public static void?
  9. 将文件保存到数据库中
  10. 阿里云HBase产品体系架构及特性解析
  11. 区块链如何解决电商供应的问题?
  12. python循环语句while教案_while循环教学设计
  13. 硬盘柱面损坏怎么办_硬盘扇区损坏怎么办
  14. 公园遛狗(小 * 逛公园)
  15. Tomcat正常启动却访问不了·解决方法
  16. 框架—— Serverlet
  17. Atom - 介绍和使用方法(好用的文本编辑器,代码提示高亮、Markdown)
  18. java 图片合成_java 将两张相片合成一张,开发实用类
  19. 简单句 - 主谓/主谓宾/主系表的分析
  20. pandas计算最大回撤

热门文章

  1. [Dask使用实例]Dask简单计算实例(map, submit)
  2. 基本粒子群算法(PSO)的改进
  3. 数据挖掘Apriori算法
  4. 小甲鱼python数字游戏给三次机会_【python 入门案例】小甲鱼python入门 猜数字游戏...
  5. LCD编程_LCD控制器
  6. Python3 JSON处理
  7. vs--bookmark用法
  8. session 的用法
  9. Android基于mAppWidget实现手绘地图(五)--如何创建地图资源
  10. 在Linux下使用screen使用退出远程终端后程序依然自动进行