1、集合
新版本python中,集合由内置类set实现,可直接使用。
>>> set(range(1,10,2))
{1, 3, 5, 7, 9}
集合会忽略重复元素,且元素排列顺序不确定。
pass
2、堆
它是一种优先队列。优先队列让你能够以任意顺序添加对象,并随时(可能是在两次添加对象之间)找出(并删除)最小的元素。相比于列表方法min效率高很多。
实际上,Python没有独立的堆类型,只有一个包含一些堆操作函数的模块。这个模块名为heapq(其中q表示队列),它包含6个函数,前4个与堆操作直接相关。必须使用列表来表示堆对象本身。
函数 | 描述 |
---|---|
heappush(heap,x) | 将x压入堆中 |
heappop(heap) | 从堆中弹出最小的元素 |
heapify(heap) | 让列表具备堆特征 |
heapreplace(heap,x) | 弹出最小的元素,并将x压入堆中 |
nlargest(n,iter) | 返回iter中n个最大的元素 |
nsmallest(n,iter) | 返回iter中n个最小的元素 |
#heappush()
>>> from heapq import *
>>> heap = []
>>> for n in range(10):
heappush(heap,n)
>>> heap #heappush()不能用于普通列表,只能用于使用堆函数创建的列表。
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #因为堆元素排序有规律:位置i处元素总是大于i//2处的元素。这是底层堆运算的基础,称为堆特征。
>>> from random import shuffle
>>> data = list(range(10))
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> shuffle(data)
>>> data
[7, 4, 6, 1, 5, 2, 9, 8, 3, 0]
>>> heap = []
>>> for n in data:
heappush(heap,n)
>>> heap
[0, 1, 2, 4, 3, 6, 9, 8, 7, 5]
>>> heappush(heap,0.5) #heappush()作用:在堆中添加一个元素。
>>> heap
[0, 0.5, 2, 4, 1, 6, 9, 8, 7, 5, 3]
#heappop(),弹出最小元素(总是位于索引0处),并且确保剩下元素保持堆特征。
>>> heap
[0, 0.5, 2, 4, 1, 6, 9, 8, 7, 5, 3]
>>> heappop(heap)
0
>>> heap
[0.5, 1, 2, 4, 3, 6, 9, 8, 7, 5]
>>> heappop(heap)
0.5
>>> heap
[1, 3, 2, 4, 5, 6, 9, 8, 7]
#heapify()通过执行尽可能少的位移操作将列表变成合法的堆(具备堆特征)。
>>> heap = [1,2,3,4,5,6,7,8,9,0]
>>> heapify(heap)
>>> heap
[0, 1, 3, 4, 2, 6, 7, 8, 9, 5]
#heapreplace()弹出最小元素,再压入一个新元素。
>>> heap
[0.5,1,5,3,2,7,9,8,4,6]
>>> heapreplace(heap,10)
0.5
>>> heap
[1,2,5,3,6,7,9,8,4,10]
3、双端队列
在需要按添加元素的顺序进行删除时,双端队列很有用。
>>> from collections import deque
>>> q = deque(range(5))
>>> q
deque([0, 1, 2, 3, 4])
>>> q.append(5) #可以左添加
>>> q.appendleft(6) #也可以右添加
>>> q
deque([6, 0, 1, 2, 3, 4, 5])
>>> q.pop() #可以左删除
5
>>> q.popleft() #也可以右删除
6
>>> q
deque([0, 1, 2, 3, 4])
>>> q.rotate(3) #后三个元素移到队首
>>> q
deque([2, 3, 4, 0, 1])
>>> q.rotate(1) #最后一个元素移到队首
>>> q
deque([1, 2, 3, 4, 0])
>>> q.rotate(2) #后两个元素移到队首
>>> q
deque([4, 0, 1, 2, 3])
4、模块time
包含用于获取当前时间、操作时间和日期、从字符串中读取日期、将日期格式化为字符串的函数。日期可表示为实数(从“新纪元”1月1日0时起过去的秒数。“新纪元”是一个随平台而异的年份,在UNIX中为1970年),也可表示为包含9位整数的元组。如(2008,1,21,12,2,56,0,21,0)表示2008年1月21日12时2分56秒,这一天是星期一,2008年的第21天(不考虑夏令时)。
Python中日期元素的字段
索引 | 字段 | 值 |
---|---|---|
0 | 年 | 如2018 |
1 | 月 | 1~12 |
2 | 日 | 1~31 |
3 | 时 | 0~23 |
4 | 分 | 0~59 |
5 | 秒 | 0~61(闰年) |
6 | 星期 | 0~6(0为星期一) |
7 | 儒略日 | 1~366 |
8 | 夏令时 | 0、1或-1 |
夏令时数字是一个布尔值(True或False),但如果使用-1,那么mktime [ 将时间元组转换为时间戳(从新纪元开始后的秒数) 的函数] 可能得到正确的值。
模块time中一些重要的函数
函数 | 描述 |
---|---|
asctime([tuple]) | 将时间元组转换为字符串 |
localtime([secs]) | centered |
mktime(tuple) | are neat |
sleep(secs) | 休眠(什么都不做) secs秒 |
striptime(string[,format]) | 将字符串转换为时间元组 |
time() | 当前时间(从新纪元开始后的秒数,以UTC为准) |
>>> import time
>>> time.asctime()
'Mon Aug 13 22:58:12 2018'
>>> time.localtime()
>>> time.struct_time(tm_year=2018, tm_mon=8, tm_mday=13, tm_hour=22, tm_min=58, tm_sec=38, tm_wday=0, tm_yday=225, tm_isdst=0)
>>> time.strptime('Mon Aug 13 22:58:12 2018')
time.struct_time(tm_year=2018, tm_mon=8, tm_mday=13, tm_hour=22, tm_min=58, tm_sec=12, tm_wday=0, tm_yday=225, tm_isdst=-1)
5、模块random
包含生成伪随机数的函数,有助于编写模拟程序或生成随机输出的程序。请注意,虽然这些函数生成的数字好像是完全随机的,但它们背后的系统是可预测的。如果要求真正的随机(如用于加密或实现与安全相关的功能),应考虑使用模块os中的函数urandom。模块random中的函数SystemRandom类基于的功能与urandom类似,可提供接近于真正随机的数据。
模块random的一些重要的函数
函数 | 描述 |
---|---|
random() | 返回一个0~1(含)的随机实数 |
getrandbits(n) | 以长实数方式返回n个随机的二进制位 |
uniform(a,b) | 返回一个a~b(含)的随机实数 |
randrange([start],stop,[step]) | 从range(start,stop,step)中随机地选择一个数 |
choice(seq) | 从序列seq中随机地选择一个元素 |
shuffle(seq[,random]) | 就地打乱序列seq |
sample(seq,n) | 从序列seq中随机地选择n个值不同的元素 |
>>> import random
>>> random.random()
0.08968567002141803
>>> random.random()
0.8316540189763981
>>> random.getrandbits(12)
2532
>>> random.getrandbits(4)
12
>>> random.uniform(1,2)
1.4238137189490196
>>> random.uniform(3,4)
3.3753276314879472
>>> random.choice([1,23,4,5,6])
6
>>> random.choice([1,2,3,4,5,6,78])
5
>>> a = [1,2,3,4,5,6,7,8,9]
>>> random.shuffle(a)
>>> a
[6, 2, 1, 9, 4, 8, 7, 5, 3]
>>> random.sample(a,3)
[1, 8, 9]
>>> random.sample(a,5)
[1, 9, 4, 2, 5]
6、shelve和json
模块shelve用于文件存储(简单的存储方案)。其中的函数open()是将一个文件名作为参数,返回一个Shelf对象,以存储数据。可以像普通字典那样错做它(只是键必须是字符串),操作完毕(并将所做的修改存盘)时,可调用方法open。
shelve.open返回的对象并非普通映射。
>>> import shelve
>>> s = shelve.open('test.dat')
>>> s['x'] = ['a','b','c']
>>> s['x'].append('d')
>>> s['x']
['a', 'b', 'c']
>>> temp = s['x']
>>> temp.append('d')
>>> s['x'] = temp
>>> s['x']
['a', 'b', 'c', 'd']
pass
7、模块re
模块re提供了对正则表达式的支持。正则表达式是可匹配文字片段的模式。最简单的正则表达式为字符串,与它们自己匹配。换而言之,正则表达式 ‘ python ’ 与字符串 ‘ python ’ 匹配。可使用这种匹配行为来完成如下工作:在文本中查找模式,将特定的模式替换为计算得到的值,以及将文本分隔成片段。
通配符
正则表达式可与多个字符串匹配,可使用特殊字符串来创建这种正则表达式。例如,句点与处换行符外的其他字符都匹配,因此正则表达式 ’ .ython ’ 与字符串 ’ python ’ 和 ‘jython’ 都匹配,还与 ’ qython ’ , ’ +ython ’ 和 ’ ython ‘(空格) 匹配,但不与 ’ cpython ’ 和’ython’匹配,因为点句只与一个字符匹配,不与零或一个以上字符匹配。
句点与除换行符外的任何字符都匹配,因此被称为通配符。
对特殊字符进行转义
普通字符只与自己匹配,但特殊字符的情况完全不同。例如,假设要匹配字符串 ‘python.org’,直接使用会与’pythonzorg’匹配。要让特殊字符的行为与普通字符一样,要对其进行转义:前面加上反斜杠\。为表示模块re要求的单个反斜杠,需要在字符串前加两个反斜杠,让解释器对其进行转义。
字符集
匹配任何字符很有用,但有时需要更细致地控制。为此,可用方括号将一个子串括起,创建一个所谓的字符集。这样的字符集与其包含的字符都匹配,如’[pg]ython’与’python’和’jython’都匹配。此外,还可以设置范围,如’[a-z]’与a~z的任何字母都匹配。还可以组合多个访问,方法是依次列出它们,如’[a-zA-Z0-9]’与大写字母、小写字母和数字都匹配。但注意,字符集只能匹配一个字符。
要指定排除字符集,可以在开头添加^,如’[^abc]’与处a、b和c外的其他字符都匹配。
二选一和子模式
需要以不同的方式处理每个字符时,字符集很好,但如果只想匹配字符串’python’和’perl’,使用字符集或通配符无法指定这样的模式,必须使用表示二选一的特殊字符|。所需的模式为’python|perl’。
如果不想二选一运算符作用于整个模式,只作用模式的一部分,可以将这部分(子模式)放在圆括号内,即’p(ython|erl)’。注意,单个字符也可称为子模式。
可选模式和重复模式
通过在子模式后面加上问号,可将其指定为可选的,即可包含可不包含。如下:
r'(http://)?(www\.)?python|.org'
只与’http://www.python.org‘、’http://python.org‘、’www.python.org’和’python.org’匹配。其中,为了减少所需的反斜杠数量,使用了原始字符串r。
另外,问号表示可选的子模式可出现一次或者不出现,还有其他几个运算符可用于子模式的重复多次。(pattern)*表示pattern可重复0、1或多次。(pattern)+表示pattern可重复1或多次。(pattern){m,n}表示模式可重复m~n次。
字符串的开头和末尾
pass
8、模块re的内容
模块re中一些重要的函数
函数 | 描述 |
---|---|
compile(pattern[,flags]) | 根据包含正则表达式的字符串创建模式对象 |
search(pattern,string[,flags]) | 在字符串中查找模式 |
match(pattern,string[,flags]) | 在字符串开头匹配模式 |
split(pattern,string[,maxsplit=0]) | 根据模式来分隔字符串 |
findall(pattern,string) | 返回一个列表,其中包含字符串中所有与模式匹配的子串 |
sub(pat,repl,string[,count=0]) | 将字符串中与模式pat匹配的子串都替换为repl |
escape(string) | 对字符串中所有的正则表达式特殊字符都进行转义 |
>>> import re
>>> some_text = 'alpha,beta,,,,gamma delta'
#search()函数
>>> re.search('[,]+',some_text)
<re.Match object; span=(5, 6), match=','>
>>> re.search('[l]+',some_text)
<re.Match object; span=(1, 2), match='l'>
#match()函数
>>> re.match('[a]+',some_text) #查找第一个与指定正则表达式匹配的子串
<re.Match object; span=(0, 1), match='a'>
>>> re.match('[l]+',some_text) #re.search()如果找到指定子串,有就返回MatchObject(结果为真),否则返回None(假)
>>>
#split()函数
>>> re.split('[, ]+',some_text)
['alpha', 'beta', 'gamma', 'delta']
>>> re.split('[, ]+',some_text,maxsplit=2)
['alpha', 'beta', 'gamma delta']
>>> re.split('[,]+',some_text,maxsplit=1)
['alpha', 'beta,,,,gamma delta']
#findall()函数
text = '"Hm...Err--are you sure?" he said, sounding insecure.'
re.findall(pat,text)
['are ', 'you ', 'he ', 'sounding ']
pat = '[a-zA-Z]+'
re.findall(pat,text)
['Hm', 'Err', 'are', 'you', 'sure', 'he', 'said', 'sounding', 'insecure']
pat = '[.?\-",]+'
re.findall(pat,text)
['"', '...', '--', '?"', ',', '.']
#sub()函数
pat = '{name}'
text = 'Dear {name}'
re.sub(pat,'Mr. Gumby',text)
'Dear Mr. Gumby'
\d可以匹配一个数字,\w可以匹配一个字母或者数字,如’00\d’可以匹配007,008,不能匹配00A。\s为空格,\s+至少一个空位。
要更精准的匹配,可以使用范围[ ],如[0-9a-zA-Z_]可以匹配一个数字或者字母或者一个_。若[pattern]+就是匹配至少一个,[pattern]*可以匹配任意个,[pattern]{n,m}可以匹配n~m个。^表示行的开头,^\d表示必须以数字开头。
表示行的结束,\d 表 示 行 的 结 束 , \d $表示以数字结尾。
re.escape是一个工具函数,用于对字符串中所有可能被视为正则表达式运算符的字符进行转义。
使用这个函数的情况有:字符串很长,其中包含大量特殊字符,而你不想输入大量的反斜杠;你从用户那里获取了一个字符串(例如通过input),想将其用于正则表达式中。
>>> re.escape('http://www.python.com')
'http://www\\.python\\.com'
>>> re.escape('Hello, world!')
'Hello,\\ world!'
匹配对象和编组
在模块re中,查找与模式匹配的子串的函数都在找到时返回MatchObject对象。这种对象包含与模式匹配的子串,还包含模式的哪部分与子串的哪部分匹配的信息。这些子串部分称为编组。
编组就是放在圆括号内的子模式,它们是根据左边的括号数编号的,其中编组0指的是整个模式。举例如下:
’ There (was a (wee) (cooper) ) who (lived in Eyfe) ’
包含如下编组:
0 There was a wee cooper who lived in Eyfe
1 was a wee cooper
2 wee
3 cooper
4 lived in Eyfe
re匹配对象的重要方法
方法 | 描述 |
---|---|
group([group1,…]) | 获取与给定子模式(编组)匹配的子串 |
start([group]) | 返回与给定编组匹配的子串的起始位置 |
end([group]) | 返回与给定编组匹配的子串的终止位置(与切片一样,不包含终止位置) |
span([group]) | 返回与给定编组匹配的子串的起始和终止位置 |
>>> m = re.match(r'www\.(jav.)(.*)\..{3}','www.javapythonc++.com')
>>> m.group(0) #编组0(整个字符串)
'www.javapythonc++.com'
>>> m.group(1) #编组1,与格式(jav.)匹配
'java'
>>> m.group(2) #编组2,与格式(.*)匹配
'pythonc++'
>>> m.start(1) #编组1起始位置
4
>>> m.start(2) #编组2起始位置
8
>>> m.end(1) #编组1终止位置
8
>>> m.span(1) #编组1跨度
(4, 8)
替换中的组号和函数
pass
贪婪和非贪婪模式
正则匹配默认是贪婪匹配,及匹配尽可能多的字符。
>>> re.match(r'^(\d+)(0*)$','102300').groups()
('102300', '')
>>> re.match(r'^(\d+?)(0*)$','102300').groups()
('1023', '00')
>>> emphasis_pattern = r'\*(.+)\*'
>>> re.sub(emphasis_pattern,r'<em>\1</em>','*This* is *it*!')
'<em>This* is *it</em>!'
>>> emphasis_pattern = r'\*(.+?)\*'
>>> re.sub(emphasis_pattern,r'<em>\1</em>','*This* is *it*!')
'<em>This</em> is <em>it</em>!'
>>> emphasis_pattern = r'\*\*(.+?)\*\*'
>>> re.sub(emphasis_pattern,r'<em>\1</em>','**This** is **it**!')
'<em>This</em> is <em>it</em>!'