Python基础学习(一)

最近花了点时间终于把Python拿起来学习下了(拖了N久了),虽然编程代码最终还是要落实到实际操作中多写才行,但是刚开始的基础语法学习还是比较重要(特别对于我这种半路出家的而言)。

虽然现在编程学习的网上资源非常多(尤其Python),但是我还是喜欢先从书看起,比如最先看的<【笨办法】学Pyhthon>这本书,把前面基础语法部分翻了后才发现是Python2的,果断放弃了,对于新入门的人来说,有Python3为何还要学Pyhton2呢。后来看了,应用场景讲了不少,但是基础语法却不够深入。最后还是挑了<Python基础教程第三版>,至少基础知识讲的蛮详细的,适合像我这种新手的入门学习

Python的入门IDE一般书籍都推荐Python软件自带的官方IDLE了,试了Spyder和Jupyter,都蛮好用的,暂时用Spyder(类似Rstuido-server版)作为入门IDE。。。

Jupyter安装如下:

pip3 install --upgrade pip
pip3 install jupyter
jupyter notebook

Spyder建议还是用Anaconda来安装,一大把Python软件都一起装好了,包括Jupyter。。。

结合已有的Perl和R的基础,对于Python的简单实用方面做对照,进而通过类比的方式做笔记

基础知识

在R语言中,如果忘记某个函数的用法,最顺手的做法即用help()或者?或者来查看帮助文档,而Python也是用帮助函数help(),比如查看某个自带函数用法help(isinstance),查看模块下的函数help(math)(先导入import(math)),查看模块下特定函数的帮助说明help(math.isnan)

Python注释分单行注释#和多行注释'''或者"""

字符串拼接:"AAA" + "BBB",字符串变量拼接:x + y,如果一个x是字符串,y是数字,则需要先将y转化为字符串再拼接:x + str(y)

Python中反斜杠\是用于转义的,如果想保留\原本的作用并在print时不会报错,可以再加一个\\,或者开头加个r print(r"C:\tmp")

Python语言中的变量不需要事先定义好类型(不像Perl需要先声明变量的类),这点跟R有点相似

多行语句可以用\来实现,类似于shell脚本中的命令换行\

a = "aaa" + \
    "bbb" + \
    "ccc"

序列解包,将序列解包分配到各个变量中,这点跟Perl相似:

x, y, z = (1,2,3)
x, y, z = [1,2,3]
key, value = {"a":"aaa", "b":"bbb"}.popitem() #popitem函数是随机获取一个键-值

但Python可以通过*收集多余的值放到列表中

x, *y, z = "abcde"
y
['b', 'c', 'd']

type()函数来获取类型,用isinstance()函数来判断类型

x = (1,2,3)
type(x)
isinstance(x, tuple)

print默认是换行输出,如果想不换行,则加end=""参数

print(x, end="")

当print输出多个变量(表达式)时,输出结果是以空格分割的,如果想变量和字符串一起输出(不间隔空格),则用+拼接(这点上不如Perl方便了,Perl对于一些能省的地方,绝对不搞复杂)

a = "aaa"
b = "bbb"
print(a + ",", b + "\n")

如需要以特定分隔符输出变量(字符串),则:

print(a, b, "ccc", sep = "-")

Python支持多种内置函数,其中丰富的数学运算函数(这点是做数据分析必须的),这点比Perl好多了,方便使用,如:

print(sum(range(10)))
print(round(10/3))

range的结果是生成器对象,不能直接print,需要先list或者tuple转化

print(list(range(1,10,1)))
>>>[1, 2, 3, 4, 5, 6, 7, 8, 9]

上面的range()即Python的内置函数,Python内置函数大概有几十种,常见的如open()repr()tuple()list()dict()等等

运算符

Python的运算符感觉整体上跟Perl和R差不多,只有点略微的区别,算数运算符基本一样

比较运算符跟R基本一样,==表示相等,!=表示不等于,>=表示大于等于。。等等

赋值运算符跟Perl基本一样,有很方便的+=+=等等,后者也可用于字符串的拼接

位运算符中,与用&,或用|,这跟Perl有点太一样,容易搞混;Perl对于&|是当做逻辑运算符的,类同于andor,当然还有not

Python的逻辑运算符则是基本上跟Perl一样,就是andornot,常见用法,判断某个变量(line)存在与否:

if not line:
    pass

除了上述运算符外,还有成员运算符和身份运算符,个人觉得很好用;这个Perl是没有的,需要用其他方法来实现;前者有:innot in,这个功能在R语言中则是%in%,其主要用于判断某值是否在序列中存在,如:

print("aaa" in "aaabbb")
print("a" in ["a", "b"])
print("a" in ("a", "b"))

条件和循环语句

每个脚本语言的条件语句if else都大同小异,只是写的语法方式不同罢了;Python的条件语句如下(除了elif跟Perl和R不太一样):

num = 5
if num == 3:
    print(3)
elif num > 3:
    print("above 3")
else:
    print("under 3")

如果多个条件一起判断,则用布尔运算符连接多个条件语句即可(布尔优先级低于比较运算符的)

if (num >= 0 and num <= 3) or (num >= 5 and num <= 8):
    print("low")
else:
    print("high")

while循环很常见,几乎每个编程语言里都有,在普通文本处理中,用while循环来依次读取文件的每行并处理是一个很常见的思路,也可以用于循环多次执行的语句,写法都差不多,跟Perl和R不太一样的地方就是不用中括号了,有时小括号也可以省

while a < 10:
    a += 1
    print(a)

其实我发现Python中循环用的最为频繁算是for循环了,就连读取每行文件也可以用for循环,历遍列表(序列)用for循环等等;for循环用法跟R比较相似

for num in [1,2,3,4,5]:
    print(num)

for也可以有效历遍字典的键

d = {"x":1, "y":2, "z":3}
for key in d:
    print(key, d[key])

以及配合item()函数,对其产生的元组进行解包

for key, value in d.items():
    print(key, value)

此外对于历遍(迭代),还有个比较有意思的内置函数zip,可以将两个序列合并在一起成一个元组(长度不一致,以短的为主),其结果可以直接拿来用于for循环,但不能直接print,因为是一个对象(跟range结果类似),所以要print的话可以先用list()函数转化下

print(list(zip([1,3,5], [2,4,6])))

除了zip,还有个enumerate()函数可以在用for循环历遍时,同时获取序列的索引和对应的值

for index, value in enumerate("abc"):
    print(index, value)

对于满足某个条件时直接跳出循环是用break,而跳过当前这次循环是用continue,跟R和Perl略微有点不一样;除了上述两种方式外,Python还有个循环中的else语句,其作用在于没有调用break时执行

Python模块(包)

Python有很多模块(类似于R的包;Perl的模块)可供选择,类似于R语言的包和Perl的模块,极大方便了日常一些常规的需求:

模块安装方法:

  • 一般习惯性先用pip安装pip install numpy
  • 不行的话就先下载模块包,解压进入目录后,再python setup.py install
  • 再不行就试试easy_install来安装模块

一般使用模块以下几个方法(类似于R的libary()require()

  • 导入整个模块:imoprt math,那么使用该模块下某个函数时,需要加上模块的名字,如:math.sqrt
  • 导入模块中的某个函数:from math import sqrt,这里就不用再后续使用sqrt函数时再加上模块名了,一次性的导入多个函数:from sys import argv,path,这里的argv函数相当于Perl的ARGV以及R语言的commandArgs(),但看起来Python的比起Perl和R的都好用些;path函数则是Python的搜索模块的路径集,一个list
  • 导入模块中的所有函数:from math import *
  • 如果有函数重名,可以使用as指定别名:from math import sqrt as foobar

Python对于模块位置的搜索路径稍微有点多样化,不像R一般就在libaray目录下,Python搜索顺序如下:

  • 当前目录(可以理解为程序所在的根目录)
  • PYTHONPATH环境变量设置的目录,可以在~/.bashrc设定PYTHONPATH
  • 标准库所在目录
  • .pth文件列出的目录(不常见),可以用site.getsitepackages()查看(先import site
  • 第三方扩展模块的所在目录,一般就是我们经常见的site-package目录

搜索路径存放在sys模块的path变量中

import sys
sys.path

读取文件

Python通过open函数读取文件,并返回一个对象,接着用一些基本方法(read/write)对这个对象操作;这点与Perl比较类似,Perl是用open函数读取文件到句柄中,然后打句柄操作从而达到读取文件的目的;而R就稍微有点不一样,用read.table等函数读取文件

Python的open函数有多种文件模式,默认是读取模式(r):

常用mode:
* ‘r’:只读
* ‘w’:只写(文件不存在则创建新文件)
* ‘a’:追写(文件不存在则创建新文件)

‘+’ 表示读写模式,可与’r’和’w’等其他模式搭配使用,’r+’和’w+’均表示可读写,两者的区别在于:后者在使用时,会先将原有内容删除,而前者不会;如果文件不存在,前者会报错,而后者不会

‘b’ 表示二进制模式,也是跟其他模式搭配使用,用于非文件格式内容(如图片等);’t’ 表示文本模式,所以其实默认模式是’rt’

一般读取/写入文件如下,最后也要像Perl关闭句柄一样,用close来关闭文件

f = open("rosalind_ini6.txt")
f.read()

f = open("res.txt", "w")
f.write("aaa")
f.close()

上述read()函数是一次性读入文件中所有内容,如果指定size,如read(size=5),则是按照字节数去读文件(5个字节),默认是-1,表示读到文件最后;还有个seek方法(Perl也有seek函数),seek(offset, whence=0),可以将读入/写入的位置移到特定的位置,有时蛮有用;也可以配合tell函数使用,其是告诉当前位置

但一般我们都是成行读入/写入,这是需要使用readline()和readlines()函数,前者读取一行,后者读取多行并返回一个list;对其对应的则是write()和writelines(),前者输入的是字符串,后者则是要列表

file = open("rosalind_ini5.txt")
while(1):
    line = file.readline().strip()
    if not line:
        break
    print(line)
f.close()

如果用reanlines()函数,则:

with open("rosalind_ini5.txt") as file:
    for line in file.readlines():
        print(line.strip())

上述代码中strip()函数的作用是为了去掉读入每行字符串头尾的字符(默认是空格或换行符),主要是因为print函数自带换行。。strip()相当于一起执行了lstrip()和rstrip(),也类似于Perl的chomp;

一般现在有更加方便的写法:

with open("rosalind_ini5.txt") as file:
    for line in file:
#        print(file.readline().strip())
        print(line.strip())

同时对两个文件分别进行读写(读入,小写都转化为大写后,写入):

with open("rosalind_ini5.txt") as file, open("res.txt", "w") as outfile:
    for line in file:
        print(line.strip())
        outfile.write(line.upper())

由于Python写入文件时,并不是立即将数据写入硬盘中,而是在内存中缓存起来,等close()后再把缓存的数据写入硬盘中,最后关闭文件;如果想写入一次就保存一次(以防程序崩溃导致数据丢失),可以使用flush()函数

with open("rosalind_ini5.txt") as file, open("res.txt", "w") as outfile:
    for line in file:
        outfile.write(line.upper())
        outfile.flush()

另外如果想对读取文件的编码方式进行设置,就像R语言read.table()函数中的
fileEncoding/encoding参数

file = open("rosalind_ini5.txt", encoding="gbk")

参考网站:
Python 基础教程

本文出自于http://www.bioinfo-scrounger.com转载请注明出处