Python学习教程(三)
函数操作
函数是重用的程序段。它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次地运行这个语句块。这被称为 调用
函数。我们已经使用了许多内建的函数,比如len
和range
。
函数通过def
关键字定义。def
关键字后跟一个函数的 标识符
名称,然后跟一对圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。
def print_hello():
print "Hello, you!"
print_hello()
Hello, you!
def hello(who):
print "Hello, %s!" % who
hello('you')
hello('me')
Hello, you!
Hello, me!
print "把之前写过的语句块稍微包装下就是函数了\n"
def findAll(string, pattern):
posL = []
pos = 0
for i in string:
pos += 1
if i == pattern:
posL.append(pos)
#-------------------
return posL
#------END of findAll-------
a = findAll("ABCDEFDEACFBACACA", "A")
print a
print findAll("ABCDEFDEACFBACACA", "B")
把之前写过的语句块稍微包装下就是函数了
[1, 9, 13, 15, 17]
[2, 12]
def read(file):
aDict = {}
for line in open(file):
if line[0] == '>':
name = line.strip()
aDict[name] = []
else:
aDict[name].append(line.strip())
#----------------------------------
for name, lineL in aDict.items():
aDict[name] = ''.join(lineL)
return aDict
print read("data/test1.fa")
read("data/test2.fa")
{'>NM_0112835 gene=Rp15 CDS=128-6412': 'AATAAATCCAAAGACATTTGTTTACGTGAAACAAGCAGGTTGCATATCCAGTGACGTTTATACAGACCAC', '>NM_011283 gene=Rp1 CDS=128-6412': 'AATAAATCCAAAGACATTTGTTTACGTGAAACAAGCAGGTTGCATATCCAGTGACGTTTATACAGACCAC', '>NM_001011874 gene=Xkr4 CDS=151-2091': 'gcggcggcgggcgagcgggcgctggagtaggagctggggagcggcgcggccggggaaggaagccagggcg', '>NM_001195662 gene=Rp1 CDS=55-909': 'AGGTCTCACCCAAAATGAGTGACACACCTTCTACTAGTTTCTCCATGATTCATCTGACTTCTGAAGGTCA'}
{'>NM_001011874 gene=Xkr4 CDS=151-2091': 'gcggcggcgggcgagcgggcgctggagtaggagctggggagcggcgcggccggggaaggaagccagggcgaggcgaggaggtggcgggaggaggagacagcagggacaggTGTCAGATAAAGGAGTGCTCTCCTCCGCTGCCGAGGCATCATGGCCGCTAAGTCAGACGGGAGGCTGAAGATGAAGAAGAGCAGCGACGTGGCGTTCACCCCGCTGCAGAACTCGGACAATTCGGGCTCTGTGCAAGGACTGGCTCCAGGCTTGCCGTCGGGGTCCGGAG',
'>NM_001195662 gene=Rp1 CDS=55-909': 'AAGCTCAGCCTTTGCTCAGATTCTCCTCTTGATGAAACAAAGGGATTTCTGCACATGCTTGAGAAATTGCAGGTCTCACCCAAAATGAGTGACACACCTTCTACTAGTTTCTCCATGATTCATCTGACTTCTGAAGGTCAAGTTCCTTCCCCTCGCCATTCAAATATCACTCATCCTGTAGTGGCTAAACGCATCAGTTTCTATAAGAGTGGAGACCCACAGTTTGGCGGCGTTCGGGTGGTGGTCAACCCTCGTTCCTTTAAGACTTTTGACGCTCTGCTGGACAGTTTATCCAGGAAGGTACCCCTGCCCTTTGGGGTAAGGAACATCAGCACGCCCCGTGGACGACACAGCATCACCAGGCTGGAGGAGCTAGAGGACGGCAAGTCTTATGTGTGCTCCCACAATAAGAAGGTGCTG',
'>NM_011283 gene=Rp1 CDS=128-6412': 'AATAAATCCAAAGACATTTGTTTACGTGAAACAAGCAGGTTGCATATCCAGTGACGTTTATACAGACCACACAAACTATTTACTCTTTTCTTCGTAAGGAAAGGTTCAACTTCTGGTCTCACCCAAAATGAGTGACACACCTTCTACTAGTTTCTCCATGATTCATCTGACTTCTGAAGGTCAAGTTCCTTCCCCTCGCCATTCAAATATCACTCATCCTGTAGTGGCTAAACGCATCAGTTTCTATAAGAGTGGAGACCCACAGTTTGGCGGCGTTCGGGTGGTGGTCAACCCTCGTTCCTTTAAGACTTTTGACGCTCTGCTGGACAGTTTATCCAGGAAGGTACCCCTGCCCTTTGGGGTAAGGAACATCAGCACGCCCCGTGGACGACACAGCATCACCAGGCTGGAGGAGCTAGAGGACGGCAAGTCTTATGTGTGCTCCCACAATAAGAAGGTGCTGCCAGTTGACCTGGACAAGGCCCGCAGGCGCCCTCGGCCCTGGCTGAGTAGTCGCTCCATAAGCACGCATGTGCAGCTCTGTCCTGCAACTGCCAATATGTCCACCATGGCACCTGGCATGCTCCGTGCCCCAAGGAGGCTCGTGGTCTTCCGGAATGGTGACCCGAA',
'>NM_0112835 gene=Rp1 CDS=128-6412': 'AATAAATCCAAAGACATTTGTTTACGTGAAACAAGCAGGTTGCATATCCAGTGACGTTTATACAGACCACACAAACTATTTACTCTTTTCTTCGTAAGGAAAGGTTCAACTTCTGGTCTCACCCAAAATGAGTGACACACCTTCTACTAGTTTCTCCATGATTCATCTGACTTCTGAAGGTCAAGTTCCTTCCCCTCGCCATTCAAATATCACTCATCCTGTAGTGGCTAAACGCATCAGTTTCTATAAGAGTGGAGACCCACAGTTTGGCGGCGTTCGGGTGGTGGTCAACCCTCGTTCCTTTAAGACTTTTGACGCTCTGCTGGACAGTTTATCCAGGAAGGTACCCCTGCCCTTTGGGGTAAGGAACATCAGCACGCCCCGTGGACGACACAGCATCACCAGGCTGGAGGAGCTAGAGGACGGCAAGTCTTATGTGTGCTCCCACAATAAGAAGGTGCTGCCAGTTGACCTGGACAAGGCCCGCAGGCGCCCTCGGCCCTGGCTGAGTAGTCGCTCCATAAGCACGCATGTGCAGCTCTGTCCTGCAACTGCCAATATGTCCACCATGGCACCTGGCATGCTCCGTGCCCCAAGGAGGCTCGTGGTCTTCCGGAATGGTGACCCGAA'}
作业(二)
将 “作业(一)” 中的程序块用函数的方式重写,并调用执行
def func(para1,para2,…):
func(para1,para2,…)
用到的知识点
备注:
每个提到提到的“用到的知识点”为相对于前面的题目新增的知识点,请综合考虑。此外,对于不同的思路并不是所有提到的知识点都会用着,而且也可能会用到未提到的知识点。但是所有知识点都在前面的讲义部分有介绍。
每个程序对于你身边会写的人来说都很简单,因此你一定要克制住,独立去把答案做出,多看错误提示,多比对程序输出结果和预期结果的差异。
学习锻炼“读程序”,即对着文件模拟整个的读入、处理过程来发现可能的逻辑问题。
程序运行没有错误不代表你写的程序完成了你的需求,你要去插眼输出结果是不是你想要的。
关于程序调试
在初写程序时,可能会出现各种各样的错误,常见的有缩进不一致,变量名字拼写错误,丢失冒号,文件名未加引号等,这时要根据错误提示查看错误类型是什么,出错的是哪一行来定位错误。当然,有的时候报错的行自身不一定有错,可能是其前面或后面的行出现了错误。
当结果不符合预期时,要学会使用print来查看每步的操作是否正确,比如我读入了字典,我就打印下字典,看看读入的是不是我想要的,是否含有不该存在的字符;或者在每个判断句、函数调入的情况下打印个字符,来跟踪程序的运行轨迹。
模块
Python内置了很多标准库,如做数学运算的 math
, 调用系统功能的 sys
, 处理正则表达式的 re
, 操作系统相关功能的 os
等。我们主要关注两个库:
sys
sys.argv 处理命令行参数
sys.exit() 退出函数
sys.stdin 标准输入
sys.stderr 标准错误
os
os.system()或os.popen() 执行系统命令
os.getcwd() 获取当前目录
os.remove() 删除文件
import os
os.getcwd()
#help(os.getcwd)
#os.remove(r'D:\project\github\PBR_training\script\splitName.py')
#os.system('rm file')
'D:\\project\\github\\PBR_training'
from os import getcwd
getcwd()
'D:\\project\\github\\PBR_training'
命令行参数
sys.argv
是一个列表,存储了包含程序名字在内的传给程序的命令行参数。
%%writefile testSys.py
import sys
print sys.argv
Writing testSys.py
%run testSys 'abc' 1
['testSys.py', "'abc'", '1']
%%writefile cat.py
import sys
def read_print_file(filename):
for line in open(filename):
print line,
#------END read_print_file--------------------------
#main函数及其调用部分是我个人写程序的固定格式,照搬就可以
def main(): #一般主程序会包含在main函数中,在文件的最后调用main函数即可运行程序
if len(sys.argv) < 2: #如果命令行参数不足两个,则提示操作
#一般提示信息输出到标准错误
print >>sys.stderr, "Usage: python %s filename" % sys.argv[0]
sys.exit(0)
file = sys.argv[1]
read_print_file(file)
#--------END main------------------
#这句话是说只有在文件被执行时才调用main函数。如果这个文件被其它文件调用,则不执行main函数。
if __name__ == '__main__':
main()
Writing cat.py
%run cat
Usage: python cat.py filename
%run cat data/test1.fa
>NM_001011874 gene=Xkr4 CDS=151-2091
gcggcggcgggcgagcgggcgctggagtaggagctggggagcggcgcggccggggaaggaagccagggcg
>NM_001195662 gene=Rp1 CDS=55-909
AGGTCTCACCCAAAATGAGTGACACACCTTCTACTAGTTTCTCCATGATTCATCTGACTTCTGAAGGTCA
>NM_0112835 gene=Rp15 CDS=128-6412
AATAAATCCAAAGACATTTGTTTACGTGAAACAAGCAGGTTGCATATCCAGTGACGTTTATACAGACCAC
>NM_011283 gene=Rp1 CDS=128-6412
AATAAATCCAAAGACATTTGTTTACGTGAAACAAGCAGGTTGCATATCCAGTGACGTTTATACAGACCAC
使用 optparse
,功能更强大 (保留内容)
%%writefile skeleton.py
#!/usr/bin/env python
desc = '''
Functional description:
'''
import sys
import os
from time import localtime, strftime
timeformat = "%Y-%m-%d %H:%M:%S"
from optparse import OptionParser as OP
def cmdparameter(argv):
if len(argv) == 1:
global desc
print >>sys.stderr, desc
cmd = 'python ' + argv[0] + ' -h'
os.system(cmd)
sys.exit(0)
usages = "%prog -i file"
parser = OP(usage=usages)
parser.add_option("-i", "--input-file", dest="filein",
metavar="FILEIN", help="The name of input file. \
Standard input is accepted.")
parser.add_option("-v", "--verbose", dest="verbose",
default=0, help="Show process information")
parser.add_option("-d", "--debug", dest="debug",
default=False, help="Debug the program")
(options, args) = parser.parse_args(argv[1:])
assert options.filein != None, "A filename needed for -i"
return (options, args)
#--------------------------------------------------------------------
def main():
options, args = cmdparameter(sys.argv)
#-----------------------------------
file = options.filein
verbose = options.verbose
debug = options.debug
#-----------------------------------
if file == '-':
fh = sys.stdin
else:
fh = open(file)
#--------------------------------
for line in fh:
pass
#-------------END reading file----------
#----close file handle for files-----
if file != '-':
fh.close()
#-----------end close fh-----------
if verbose:
print >>sys.stderr,\
"--Successful %s" % strftime(timeformat, localtime())
if __name__ == '__main__':
startTime = strftime(timeformat, localtime())
main()
endTime = strftime(timeformat, localtime())
fh = open('python.log', 'a')
print >>fh, "%s\n\tRun time : %s - %s " % \
(' '.join(sys.argv), startTime, endTime)
fh.close()
Overwriting skeleton.py
%run skeleton -h
Usage: skeleton.py -i file
Options:
-h, --help show this help message and exit
-i FILEIN, --input-file=FILEIN
The name of input file. Standard input is accepted.
-v VERBOSE, --verbose=VERBOSE
Show process information
-d DEBUG, --debug=DEBUG
Debug the program
作业(三)
使 “作业(二)” 中的程序都能接受命令行参数
import sys
sys.argv
import optparse
用到的知识点
备注
每个提到提到的“用到的知识点”为相对于前面的题目新增的知识点,请综合考虑。此外,对于不同的思路并不是所有提到的知识点都会用着,而且也可能会用到未提到的知识点。但是所有知识点都在前面的讲义部分有介绍。
每个程序对于你身边会写的人来说都很简单,因此你一定要克制住,独立去把答案做出,多看错误提示,多比对程序输出结果和预期结果的差异。
学习锻炼“读程序”,即对着文件模拟整个的读入、处理过程来发现可能的逻辑问题。
程序运行没有错误不代表你写的程序完成了你的需求,你要去插眼输出结果是不是你想要的。
关于程序调试
在初写程序时,可能会出现各种各样的错误,常见的有缩进不一致,变量名字拼写错误,丢失冒号,文件名未加引号等,这时要根据错误提示查看错误类型是什么,出错的是哪一行来定位错误。当然,有的时候报错的行自身不一定有错,可能是其前面或后面的行出现了错误。
当结果不符合预期时,要学会使用print来查看每步的操作是否正确,比如我读入了字典,我就打印下字典,看看读入的是不是我想要的,是否含有不该存在的字符;或者在每个判断句、函数调入的情况下打印个字符,来跟踪程序的运行轨迹。
更多Python内容
单语句块
if True:
print 'yes'
if True: print 'yes'
x = 5
y = 3
if x > y:
print y
else:
print x
#-------------
print y if y < x else x
print x
yes
yes
3
3
5
列表综合,生成新列表的简化的for循环
aList = [1,2,3,4,5]
bList = []
for i in aList:
bList.append(i * 2)
#-----------------------------------
#nameL = [line.strip() for line in open(file)]
bList = [i * 2 for i in aList]
print bList
[2, 4, 6, 8, 10]
print "列表综合可以做判断的"
aList = [1,2,3,4,5]
bList = [i * 2 for i in aList if i%2 != 0]
print bList
列表综合可以做判断的
[2, 6, 10]
print "列表综合也可以嵌套的"
aList = [1,2,3,4,5]
bList = [5,4,3,2,1]
bList = [i * j for i in aList for j in bList]
#for i in aList:
# for j in bList:
# print i * j
print bList
列表综合也可以嵌套的
[5, 4, 3, 2, 1, 10, 8, 6, 4, 2, 15, 12, 9, 6, 3, 20, 16, 12, 8, 4, 25, 20, 15, 10, 5]
断言,设定运行过程中必须满足的条件,当情况超出预期时报错。常用于文件读入或格式判断时,有助于预防异常的读入或操作。
a = 1
b = 2
assert a == b, "a is %s, b is %s" % (a, b)
if a == b:
pass
else:
print "a is %s, b is %s" % (a, b)
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-94-1cdfb2fe6c3a> in <module>()
1 a = 1
2 b = 2
----> 3 assert a == b, "a is %s, b is %s" % (a, b)
4
5 if a == b:
AssertionError: a is 1, b is 2
lambda, map, filer, reduce (保留节目)
lambda产生一个没有名字的函数,通常为了满足一次使用,其使用语法为
lambda argument_list: expression
。参数列表是用逗号分隔开的一个列表,表达式是这些参数的组合操作。map执行一个循环操作,使用语法为
map(func, seq)
。第一个参数是要调用的函数或函数的名字,第二个参数是一个序列(如列表、字符串、字典)。map会以序列的每个元素为参数调用func,并新建一个输出列表。filter用于过滤列表,使用语法为
filter(func, list)
。以第二个参数的每个元素调用func,返回值为True则保留,否则舍弃。reduce连续对列表的元素应用函数,使用语法为
reduce(func, list)
。如果我们有一个列表aList = [1,2,3, … ,n ], 调用reduce(func, aList)
后进行的操作为: 首先前两个元素会传入函数func做运算,返回值替换这两个元素,成为数组第一个元素aList = [func(1,2),3, … , n];然后当前的前两个元素再传图func函数做运算,返回值返回值替换这两个元素,成为数组第一个元素aList = [func(func(1,2),3), … , n],直到列表只有一个元素。
print "求和函数"
f = lambda x,y: x + y
print f([1,2,3],[4,5,6])
print f(10,15)
求和函数
[1, 2, 3, 4, 5, 6]
25
print "单个参数的map, lambda调用"
aList = [1,2,3,4,5]
print map(lambda x: x**2, aList)
print "多个参数的map, lambda调用"
f = lambda x,y: x + y
print map(f,[1,2,3],[4,5,6])
print "参数为字符串"
print map(lambda x: x.upper(), 'acdf')
单个参数的map, lambda调用
[1, 4, 9, 16, 25]
多个参数的map, lambda调用
[5, 7, 9]
参数为字符串
['A', 'C', 'D', 'F']
print "输出所有的奇数"
aList = [1,2,3,4,5]
print filter(lambda x: x%2, aList)
输出所有的奇数
[1, 3, 5]
print "列表求和"
aList = [1,2,3,4,5]
print reduce(lambda a,b: a+b, aList)
列表求和
15
print "列表取最大值"
aList = [1,2,3,4,5]
print reduce(lambda a,b: a if a > b else b, aList)
列表取最大值
5
exec, eval (执行字符串python语句, 保留节目)
a = 'print "Executing a string as a command"'
exec(a)
Executing a string as a command
a = '(2 + 3) * 5'
eval(a)
25
Reference
http://www.byteofpython.info/
http://woodpecker.org.cn/abyteofpython_cn/chinese/index.html
http://www.python-course.eu/
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-189-a-gentle-introduction-to-programming-using-python-january-iap-2008/
http://my.oschina.net/taogang/blog/286955
Python画图
%matplotlib inline
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
cset = ax.contour(X, Y, Z, cmap=cm.coolwarm)
ax.clabel(cset, fontsize=9, inline=1)
plt.show()
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
mpl.rcParams['legend.fontsize'] = 10
fig = plt.figure()
ax = fig.gca(projection='3d')
#theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
#z = np.linspace(-2, 2, 100)
#r = z**2 + 1
#x = r * np.sin(theta)
#y = r * np.cos(theta)
x = [1,2,3]
y = [1.5,1,2]
z = [2,1,3]
ax.plot(x, y, z, label='parametric curve')
ax.legend()
plt.show()
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
someX, someY = 0.5, 0.5
fig,ax = plt.subplots()
currentAxis = plt.gca()
currentAxis.add_patch(Rectangle((someX - 0.1, someY - 0.1), 0.2, 0.2,
alpha=1, facecolor='none'))
<matplotlib.patches.Rectangle at 0xa31e198>
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
x = [1,2,2]
y = [1,0,2]
z = [1,2,0]
verts = [zip(x, y,z)]
ax.add_collection3d(Poly3DCollection(verts,edgecolors='red', facecolors='red'))
x = [0,1,1]
y = [0,0,1]
z = [0,1,0]
verts = [zip(x, y,z)]
verts = [[(1,1,1), (2,0,2),(2,2,0)],[(0,0,0),(1,0,1),(1,1,0)]]
ax.add_collection3d(Poly3DCollection(verts))
plt.show()
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
verts = [[(0.5,0.5,0.5), (1.2,0,1.2),(1.2,1.2,0)],[(0,0,0),(1,0,1),(1,1,0)]]
ax.add_collection3d(Poly3DCollection(verts, edgecolors=['blue','red'], facecolors=['blue','red']))
plt.show()
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = [0.5, 1.2, 1.2, 0, 1, 1]
y = [0.5, 0, 1.2, 0, 0, 1]
z = [0.5, 1.2, 0, 0, 1, 0]
poly3d = [[(0.5,0.5,0.5), (1.2,0,1.2),(1.2,1.2,0)],[(0,0,0),(1,0,1),(1,1,0)]]
ax.scatter(x,y,z)
ax.add_collection3d(Poly3DCollection(poly3d, edgecolors=['red','blue'], facecolors='w', linewidths=1, alpha=0.5))
plt.show()