专栏名称: 生信宝典
生物信息分析入门、晋级和经验分享。Linux、R、Python学习教程;高通量测序数据分析学习教程;生信软件安装教程。所有内容均为原创分享,致力于从基础学习到提高整个过程。
目录
相关文章推荐
生信宝典  ·  Nature | ... ·  2 天前  
生信宝典  ·  Cell | ... ·  2 天前  
生物学霸  ·  有了这套写作模板,英语渣渣也能写好 SCI ·  4 天前  
生物学霸  ·  连发三篇 ... ·  5 天前  
51好读  ›  专栏  ›  生信宝典

Python学习教程(三)

生信宝典  · 公众号  · 生物  · 2017-06-26 06:58

正文

函数操作

函数是重用的程序段。它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次地运行这个语句块。这被称为 调用 函数。我们已经使用了许多内建的函数,比如lenrange

函数通过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'}

作业(二)

  1. 将 “作业(一)” 中的程序块用函数的方式重写,并调用执行

  • 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

    作业(三)

    1. 使 “作业(二)” 中的程序都能接受命令行参数

    • 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)
    
     in ()
          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'))

    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()