python常用语法比较简单,变量声明,条件判断,循环遍历,深点有面向对象,装饰器。
一些常用的数据结构和知识总结,梳理如下:
一,python基本的数据类型,常用函数
python str list set dic lambda | filter map reduce | pass,del,exec,eval from functools import reduce foo = [2, 18] print (list(filter(lambda x: x % 3 == 0, foo))) #[18] print (list(map(lambda x: x * 2 + 10, foo))) #[14, 46] print (reduce(lambda x, y: x + y, foo)) #20 print ([x * 2 + 10 for x in foo]) print ([x for x in foo if x % 3 == 0])
二,常用str和list的方法和内置函数
function: cmp(obj1, obj2) len(obj1) max(obj1) min(obj1) sum() reduce() list<==>tuple # str() 'abc' "abc" '''abc''' .find(substring, [start [,end]]).rfind(substring,[start [,end]]) .index(substring,[start [,end]])rindex(substring,[start [,end]]) .replace(old, new)..count(substring,[start [,end]]) .lowercase().capitalize().lower().upper().swapcase() .split(str, ' ')S.join(list, ' ') .encode([encoding,[errors]]).decode([encoding,[errors]]) .startwith(prefix[,start[,end]]) .endwith(suffix[,start[,end]]) .isalnum().isalpha().isdigit().isspace().islower().isupper().istitle() # list() [1, 3, 5] .append(obj).count(obj).extend(seq).index(obj).insert(index, obj). pop(obj=list[-1]).remove(obj).reverse().sort([func]) # dict() and collections.OrderedDict() .get(key, 0).has_key(key).keys().values().items() .update(dict2).popitem().clear().copy() # type() type([]) # <type 'list'> type([]).__name__ # 'list' type(type([])) # <type 'type'> isinstance(varName,varType) # True False # set() {1, 3, 5} .add().pop().remove() 比较元素-->difference() 删除两集合中相同的元素-->difference_update() 移除元素-->discard(values) 取交集值-->intersection() 取交集并更新-->intersection_update() 对称交集-->symmetric_difference() 对称交集并更新-->symmetric_difference_update() 并集-->union()
三,正则表达式re库
1)正则表达式基础 # re库的主要功能函数 # re库是Python的标准库,主要用于字符串匹配 # re库采用raw string类型表示正则表达式,表示为:r'text',raw string不包含转义字符串。 # Re库默认采用贪婪匹配,即输出匹配最长的子串 re.search() #在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 re.match() #从一个字符串的开始位置起匹配正则表达式,返回match对象 re.findall() #搜索字符串,以列表类型返回全部能匹配的子串 re.split() #将一个字符串按照正则表达式匹配结果进行分割,返回列表类型 re.finditer() #搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象 re.sub() #在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串 # . 表示任何单个字符 # [ ] 字符集,对单个字符给出取值范围 [abc]表示a、b、c,[a‐z]表示a到z单个字符 # [^ ] 非字符集,对单个字符给出排除范围 [^abc]表示非a或b或c的单个字符 # * 前一个字符0次或无限次扩展 abc* 表示ab、abc、abcc、abccc等 # + 前一个字符1次或无限次扩展 abc+ 表示abc、abcc、abccc等 # ? 前一个字符0次或1次扩展 abc? 表示ab、abc左右表达式任意一个 # {m} 扩展前一个字符m次 ab{2}c表示abbc # {m,n} 扩展前一个字符m至n次(含n) ab{1,2}c表示abc、abbc # ^ 匹配字符串开头 ^abc表示abc且在一个字符串的开头 # $ 匹配字符串结尾 abc$表示abc且在一个字符串的结尾 # ( ) 分组标记,内部只能使用 操作符 # \d 数字,等价于[0‐9] # \w 单词字符,等价于[A‐Za‐z0‐9_] # \b 匹配单词的开始或结束 # \W 非单词字符,等价于[^\w] #贪婪匹配与最小匹配 # *? 前一个字符0次或无限次扩展,最小匹配 # +? 前一个字符1次或无限次扩展,最小匹配 # ?? 前一个字符0次或1次扩展,最小匹配 # {m,n}? 扩展前一个字符m至n次(含n),最小匹配 # reGroups = re.match(r'^(\d+?)(0*)$', '102300') # reGroups = re.search(r'[1-9]\d{5}', 'BIT 100081') # reGroups = re.finditer(r'[1-9]\d{5}', 'BIT100081 TSU100084') htmlList = re.findall(r'(20(?:\d){6})', fileName.upper()) findList = re.findall(r'[1-9]\d{1}', 'BIT100081 TSU100084') # ['10', '81', '10', '84'] spltList = re.split(r'[1-9]\d{5}', 'BIT100081 TSU100084') # ['BIT', ' TSU', ''] subinStr = re.sub(r'[1-9]\d{5}', ':zipcode', 'BIT100081 TSU100084') # 'BIT:zipcode TSU:zipcode' 2)正则表达式 高阶 1,懒惰匹配和贪婪匹配,python中的正则表达式默认为惰性匹配。 贪婪匹配,尽量匹配最长串;懒惰匹配,尽量匹配最短串, >>> s = '<xxxx><xxxx><xxxx><xxxx>' >>> re.findall('<.*>', s) # ['<xxxx><xxxx><xxxx><xxxx>'] >>> re.findall('<.*?>', s) # ['<xxxx>', '<xxxx>', '<xxxx>', '<xxxx>'] # *?,+?,??,{m,n}? 前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配 a = re.findall(r"a(\d+?)",'a23b') # ['2'] b = re.findall(r"a(\d+)",'a23b') # ['23'] a = re.match('<(.*)>','<H1>title<H1>').group() # <H1>title<H1> b = re.match('<(.*?)>','<H1>title<H1>').group() # <H1> a = re.findall(r"a(\d+)b",'a3333b') # ['3333'] b = re.findall(r"a(\d+?)b",'a3333b') # ['3333'] # 注意如果前后均有限定条件的时候,就不存在贪婪模式了,非匹配模式失效。 注意体会如下差异: b = re.findall(r"a\d+?b",'a3333b3333b') # ['a3333b'] b = re.findall(r"a(\d+?)b",'a3333b3333b') # ['3333'] b = re.findall(r"a(?:\d+?)b",'a3333b3333b') # ['a3333b'] b = re.findall(r"a(?:\d+?)b(?:\d+?)b",'a3333b3333b') # ['a3333b3333b'] b = re.findall(r"a(\d+?)b(\d+?)b",'a3333b3333b') # [('3333', '3333')] b = re.findall(r"a(\d+?)b(?:\d+?)",'a3333b3333b') # ['3333'] 2,匹配模式中的分组内容 (.*) 匹配括号内的表达式,也表示一个组, 组里面的内容,可以使用 \1...\9 进行分组提取 >>> s = "i=and love u=you" >>> re.sub(r'(\w+)=(\w+)', r"[\1]:[\2]", s) # '[i]:[and] love [u]:[you]' 3,前向界定符,包括前向肯定界定符和前项否定界定符 (?=...)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。 (?!...)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 .*[.].*$ 匹配一个文件名,基本名和扩展名两部分 .*[.](?!bat$).*$ 匹配的扩展名不是 "bat" 的文件名,前向的意思:如果表达式 bat 在这里没有匹配,尝试模式的其余部分; .*[.](?!bat$|exe$).*$ 匹配不是以 "bat" 或 "exe" 结尾的文件名,如果 bat$ 或者 exe$ 匹配,整个模式将匹配失败。 .*[.](?=bat|exe).*$ 前向肯定界定符,当前位置肯定是这几个字符,匹配成功继续,失败整个表达式失败, >>> re.findall("[.]((?!bat|exe)\w)", q) # ['f'] >>> re.findall("[.]((?=bat|exe)\w)", q) # ['b', 'e'] 注意:qinaixnag前向界定符,并不占位,只用来做限定用,限定后具体提取多少位,由后面匹配原则定。 前向界定的字符串长度必须是常数,所以数量词 * + {} 胡扯,我试了27版本 * + [] 可以正常使用。
四,python2和3常见编码问题
1,文件编码,比如文件包含中文常量解码格式,2,字符串变量编码存储格式,3.控制台打印输出字符串编码的格式 2,文件的coding编码声明只代表了文件中包含字符串常量中字符以何种解码去读入,根据指定的coding编码格式解码。 coding只是告诉python使用哪种编码来读取python脚本文件,但是文件实际存储编码还是要使用跟coding一致才正确。 字符串常量u"你好"代表对去这个常量,使用以 Unicode 格式 进行编码 #!/usr/bin/env python # -*- coding: UTF-8 -*- # -*- coding: GB2312-*- #coding: UTF-8 #-*- for beauty ctring with open(‘file.txt’, 'r' , encoding =‘utf-8’) as f: pass 2,字符串变量内存存储编码Unicode格式,内存永远存储二进制byte字节。也不限制编码格式。 内存也可存储utf-8,gbk,gb2312编码的二进制字节,只要存储成Unicode控制台打印就不会乱码。 win下office的excel读取的字符大多需要gbk解码, 调用encode方法的是unicode对象,生成的是字节流;调用decode方法的是str对象(字节流) sys.setdefaultencoding() 是python2设置默认的string的编码格式,python3默认utf-8编码 sys.getdefaultencoding()是python2(ascii)和3(utf-8)通用的获取python字符串编码格式 python2 sys.getdefaultencoding() #'ascii' python3 sys.getdefaultencoding() #'utf-8' #为了防止重新设置默认编码影响原本依赖ASCII编码的程序, #Python编译器在启动时特意清除了sys模块的setdefaultencoding方法。 #如果需要调用,也可以reload(sys)再重载sys模块,它就是变成了第三方模块,可以随便更改,不会影响编译 #输入 (文件/表格 保存文件编码格式 指定读取解码格式,以及控制台输入字符串 终端输入编码:sys.stdin.encoding) #存储 (来自于文件及变量的字符串,不管什么编码格式,统一按照字节读取存储byte二进制。不改变原有编码) #输出 (从内存中按照字节取出,对于win控制台只支持gbk,如果原有字符串是bgk编码直接输出显示正常, #原有编码utf-8,需要先解码unicode再编码gbk合适) #(如果存储的是unicode则需要进行编码,在win下面控制台unicode字符串打印正产输出。print函数, # 会对输出的内容编码,终端输出编码:sys.stdout.encoding) #(对于linux和苹果机器,控制台支持utf-8,如果原有字符串是utf-8编码直接输出显示正常, # 原有编码gbk,需要先解码unicode再编码gb) #(如果什么都不指定,那应该就是使用ascii编码了,包含双字节在进行输出 # 编码都会报错提示ascii相关的问题。指定默认内存编码) # 例如:文件coding指定utf-8,字符串定义带u"你好",在win下控制台输出,即:文件要用utf-8保存, # 读取使用utf-8解码,将你好使用unicode保存,输出在进行gbk编码 # 如果字符串定义不带u,意味着读取解码utf-8使用存储也会使用使用utf-8, #你可以通过以下命令查看当前环境的编码来源: import locale locale.getpreferredencoding() locale.getdefaultlocale() 备注: 读写文件的时候,为了防止默认编解码抛异常,建议通过rb或者wb读写二进制文件,py2和py3都支持byte类型字符串。
五,Python里的OS模块常用函数说明
os.sep可以取代操作系统特定的路径分隔符。windows下为"\\" os.name字符串指示你正在使用的平台。Windows它是'nt',Linux/Unix用户,它是'posix' os.getcwd()函数得到当前工作目录,即当前Python脚本工作的目录路径。 os.getenv()获取一个环境变量,如果没有返回none os.putenv(key, value)设置一个环境变量值 os.listdir(path)返回指定目录下的所有文件和目录名。 os.remove(path)函数用来删除一个文件。 os.system(command)函数用来运行shell命令。 os.linesep字符串给出当前平台使用的行终止符。Windows使用'\r\n',Linux使用'\n'而Mac使用'\r' os.curdir:返回当前目录('.') os.chdir(dirname):改变工作目录到dirname os.path.split(p)函数返回一个路径的目录名和文件名 os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录 os.path.exists()函数用来检验给出的路径是否真地存在 os.path.getsize(name):获得文件大小,如果name是目录返回0L os.path.abspath(name):获得绝对路径 os.path.normpath(path):规范path字符串形式 os.path.splitext():分离文件名与扩展名 os.path.join(path,name):连接目录与文件名或目录 os.path.basename(path):返回文件名 os.path.dirname(path):返回文件路径
六,Python里的logging模块使用方法
def log:() import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='parser_result.log', filemode='w') console = logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter('LINE %(lineno)-4d : %(levelname)-8s %(message)s') console.setFormatter(formatter) logging.getLogger('').addHandler(console) logging.info('helloworld')
七,python中import寻找module模块的顺序
首选这个module是不是built-in即内建模块,如果是则引入内建模块,如果不是则在sys.path的list中寻找 sys.path在python执行时动态生成,A脚本执行的当前路径,B环境变量中的PYTHONPATH, C安装python时的依赖位置
八,变量作用域
1,块级作用域:python没有,比如if for里面定义的变量外层可用 2,局部作用域:python有,函数里面定义的变量外部不可用 3,作用域链:Python中有,变量会由函数内到外找,作用域执行前已定 4,函数在没有执行前,内部代码不执行,这点Python和javascript有共性 li = [lambda :x for x in range(10)] print(type(li[0])) print(li[0]()) # 9 5,函数内部的变量,无global声明直接使用,会去查找外层当做全局变量使用,不可赋值 6,函数内部的变量,如果不加global声明直接赋值定义,会被当做局部变量,跟全局无关 函数定义了本地作用域,而模块定义的是全局作用域。 如果想要在函数内定义全局作用域,需要加上global修饰符。
---------------------------------------------------------------------
正则表达式补充:
re.search() #在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 re.match() #从一个字符串的开始位置起匹配正则表达式,返回match对象 re.finditer() #搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象 re.findall() #搜索字符串,以列表类型返回全部能匹配的子串,返回列表类型 re.split() #将一个字符串按照正则表达式匹配结果进行分割,返回列表类型 re.sub() #在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串
1、普通字符和11个元字符:
普通字符 | 匹配自身 | abc | abc |
. | 匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符 | a.c | abc |
\ | 转义字符,使后一个字符改变原来的意思 | a\.c;a\\c | a.c;a\c |
* | 匹配前一个字符0或多次 | abc* | ab;abccc |
+ | 匹配前一个字符1次或无限次 | abc+ | abc;abccc |
? | 匹配一个字符0次或1次 | abc? | ab;abc |
^ | 匹配字符串开头。在多行模式中匹配每一行的开头 | ^abc | abc |
$ | 匹配字符串末尾,在多行模式中匹配每一行的末尾 | abc$ | abc |
| | 或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式 | abc|def | abc def |
{} | {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次 | ab{1,2}c | abc abbc |
[] | 字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。 所有特殊字符在字符集中都失去其原有的特殊含义。用\反斜杠转义恢复特殊字符的特殊含义。 | a[bcd]e | abe ace ade |
() | 被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1. 分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。 | (abc){2} a(123|456)c | abcabc a456c |
2、预定义字符集(可以写在字符集[...]中)
\d | 数字:[0-9] | a\bc | a1c |
\D | 非数字:[^\d] | a\Dc | abc |
\s | 匹配任何空白字符:[<空格>\t\r\n\f\v] | a\sc | a c |
\S | 非空白字符:[^\s] | a\Sc | abc |
\w | 匹配包括下划线在内的任何字字符:[A-Za-z0-9_] | a\wc | abc |
\W | 匹配非字母字符,即匹配特殊字符 | a\Wc | a c |
\A | 仅匹配字符串开头,同^ | \Aabc | abc |
\Z | 仅匹配字符串结尾,同$ | abc\Z | abc |
\b | 匹配\w和\W之间,即匹配单词边界,也就是指单词和空格间的位置。 例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 | \babc\b a\b!bc | abc a!bc |
\B | [^\b] | a\Bbc | abc |
3,正则表达式模式汇总:
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[...] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' |
[^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
re* | 匹配0个或多个的表达式。 |
re+ | 匹配1个或多个的表达式。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
re{ n} | 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。 |
re{ n,} | 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。 |
re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
a| b | 匹配a或b |
(re) | 匹配括号内的表达式,也表示一个组 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (...), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#...) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配字母数字及下划线 |
\W | 匹配非字母数字及下划线 |
\s | 匹配任意空白字符,等价于 [\t\n\r\f]. |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]. |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
\1...\9 | 匹配第n个分组的内容。 |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
遗失的美好: 1,为什么在python交互解释器和直接执行脚本中打印出来的sys.path不一样,交互解释器没有当前路径 2,为什么我从当前路径导入模块,语句报错,包的init文件也有,不明觉厉:form . import moduleX "import package_name"导入包的本质就是执行该包下的__init__.py文件,并且可以调用其定义的函数