哈希表
1、集合set
(1)集合特点
可变的、无序的、**不重复的 **元素集合
集合的定义;
s1 = set() #定义了一个空集
s5 = {} #定义了一个空字典,有一个元素都是集合,但一个也没有就是集合
s2 = set(range(5)) #set里写可迭代对象
s1,s2,s5 注意:写set时里边不可出现不可哈希类型,比如:list ,bytearray ,dic ,set
(set(), {0, 1, 2, 3, 4}, {})
(2)元素要求
set的元素要求必须可以hash
目前不可哈希的类型有:list ,bytearray ,dic ,set
元素不可索引
set可以迭代
(3)元素增加
a、add(elem)
增加一个元素到set中(因为集合无序,所以直接往里加就好)
如果元素存在,什么都不做 内容相等
s7 = {1}
s7.add('a') #在无序列表增加元素,用add
s7
{1, 'a'}
b、update(*other)
合并其他元素到set集合中,加入集合的过程会去重,去重是看内容是否相等
参数other必须是可迭代对象
就地修改
s1 = set(range(9))
s2 = set(range(10,15))
s1.update(s2) #把s2合并到s1中,就地修改没有返回值
s1,s2
({0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14}, {10, 11, 12, 13, 14})
(4)set删除
a、remove(elem)
从set中找值并移除该元素,就地修改
元素不存在,抛出keyError异常 (key是唯一的意思)
b、discard(elem)
从set中找到并移除该元素,就地修改
元素不存在,什么都不做,不会报错
c、pop
随机弹出一个值,显示该值并将其从集合移除
空集返回keyError异常
d、clear
移除所有元素(并不是真正移除,只是做个标记)
(5)修改、查询
a、修改
要么删除,要么加入新元素,没有修改操作
因为集合的元素是唯一的
b、索引
非线性结构,无法索引
因为集合是无序的
c、遍历
可以迭代所有元素,跟规模有关 O(n)
d、成员运算符
in和not in 判断是否在set中
us 微秒 -6
ns 纳秒 -9
ms 毫秒 -3
s1 = set(range(100))
s2 = set(range(1000000))
%%timeit
-1 in s1
34.7 ns ± 7.96 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
(6)set和线性结构
线性结构的查询时间复杂度是O(n),即随着数据规模的增大而增加耗时
set、dict等结构,内部使用hash值作为key,时间复杂度可以做到O(1),查询时间和数据规模无关。
可hash
数值型int、float、complex
布尔型True、False
字符串string、bytes
tuple
None
以上都是不可变类型,称为可哈希类型,hashable
set的元素必须是可hash的。
(7)集合
全集
所有元素的集合,例如实数集,所有实数组成的集合就是全集
子集subset和超集superset
一个集合A所有元素都在另一个集合B内,A是B的子集,B是A的超集
真子集和真超集
A是B的子集,且A不等于B,A就是B的真子集,B是A的真超集
a、并集
多个集合合并的结果
*union(others)
返回和多个集合合并后的新的集合
| 运算符重载
等同union
*update(others)
和多个集合合并,就地修改
| =
等同update
b、交集
多个集合的公共部分
*intersection(others)
返回和多个集合的交集
&
等同intersection
*intersetion_update(other)
获取和多个集合的交集,并就地修改
& =
等同intersection_update
c、差集
集合中除去和其他集合公共部分
*difference(other)
返回和多个集合的差集
-
等同difference
*difference_update(other)
获取和多个集合的差集并就地修改
-=
等同difference_update
d、对称差集
集合A和B,有所有不属于A和B的交集元素组成的集合,记作(A-B)并(B-A)
symmetric_difference(other)
返回和另一个集合的对称差集
^
等同symmetric_difference
symmetric_difference_update(other)
获取和另一个集合的对称差集并就地修改
^=
等同symmetric_difference_update
e、其他符号
issubset (other) <=
判断当前集合是否是另一个集合的子集
set1 < set2
判断set1是否是set2的真子集
issuperset(other) >=
判断当前集合是否是other的超集
set1 > set2
判断set1是否是set2的真超集
isdisjoint(other) 不交
当前集合和另一个集合没有交集
没有交集,返回True
2、字典dict
key—value键值对的数据的集合
特点:
key 可变的、无序的、key不重复
可hashable才可以作为Key,可以使用hash()测试
(1)字典的构造
d1 = {} #定义一个空字典
d2 = dict() #定义一个空字典
d3 = {'a':1,'b':'abc'} #要求k可hash,且不重复
d1 ,d2 ,d3
({}, {}, {'a': 1, 'b': 'abc'})
d5 = dict(a=1, b=2, c=3, d=4) #另一种定义字典的方式
d5, id(d5)
({'a': 1, 'b': 2, 'c': 3, 'd': 4}, 1984084769832)
d6 = dict(d5, a=100 ,f=22) ->mapping #用一个字典构造另一个字典,key对应的值可修改,也可新添加补重复的k
d6, id(d6)
({'a': 100, 'b': 2, 'c': 3, 'd': 4, 'f':2}, 1984011758552)
二元组
d7 = dict([(1,2),['a',100],(('ab',),'c')], a = 200)
d7
{1: 2, 'a': 200, ('ab',): 'c'}
用fromkey创建,可批量造一些k、v对出来
d8 = dict.fromkeys(range(10),1000)
d8
{0: 1000,
1: 1000,
2: 1000,
3: 1000,
4: 1000,
5: 1000,
6: 1000,
7: 1000,
8: 1000,
9: 1000}
(2)元素的访问
a、d[key]
返回key对应的值value
key不存在抛出keyError异常
b、get(key[,default])
返回Key对应的值value
key不存在就返回缺省值,如果没有设置缺省值就返回None
c、setdefaul(key[,default])
返回kye对应的值value
key不存在,就用当前的key构建一个kv对,添加kv对,value默认设置为None,并返回当前的value值
d7 = {1: 2, 'a': 200, ('ab',): 'c'}
d7[1],d7['a'] #找不到会报keyError异常
(2, 200)
d7.get(('ab',))
'c'
print(d7.get('k',1000)) #get找不到会返回缺省值默认None,缺省值可修改
None
d7 = {1: 2, 'a': 200, ('ab',): 'c'}
d7.setdefault('e') #找不到会直接创建一个新的kv对,v默认为None,可修改
d7
{1: 2, 'a': 200, ('ab',): 'c', 'c': None, 'e': None}
(3)元素的增加、修改
update([other]) —> None
使用另一个字典的kv对更新本字典
key不存在,就添加
key存在,覆盖已经存在的key对应的值
就地修改
d7
{1: 2, 'a': 200, ('ab',): 'c', 'c': None, 'd': 100, 'e': None}
d7.update({1:30},a=15,f=90) #key存在就覆盖,不存在就添加,就地更新
d7
{1: 30, 'a': 15, ('ab',): 'c', 'c': None, 'd': 100, 'e': None, 'f': 90}
(4)字典删除
a、pop(key[,default])
key存在,移除它,并返回它的value
key不存在,返回给定的default
default未设置,key不存在则抛出keyError异常
d7
{1: 30, 'a': 15, ('ab',): 'c', 'c': None, 'd': 100, 'e': None, 'f': 90}
d7.pop('f')
90
d7.pop('f')
90
b、popitem()
移除并返回一个任意的键值对
字典为empty,抛出keyError异常
d7
{1: 30, 'a': 15, ('ab',): 'c', 'c': None, 'd': 100, 'e': None, 'f': 90}
d7.popitem() #随机弹出一对kv对,并且把该kv对从字典移除
('e', None)
d7
{1: 30, 'a': 15, ('ab',): 'c', 'c': None, 'd': 100}
c、clear()
清空字典
d、del语句
del看着像删除了一个对象,本质上是减少了一个对象的引用,del实际上删除的是名称,而不是对象
(5)字典遍历
一般情况下把它当做迭代来用的时候,是用K来迭代
字典使用k来访问 O(1)
d
{'a': 1, 'b': [], 'c': [1, 3, 5]}
for k in d: for k in d.keys(): #按照k来遍历
print(k)
a
b
c
list(d) list(d.keys())
['a', 'b', 'c']
"".join(d)
'abc'
for k in d.values(): #取字典的values值
print(k)
1
[]
[1, 3, 5]
(6)defaultdict
第一个参数是default_factory,缺省是None,它提供一个初始化函数,当Key不存在的时候,会调用这个工厂函数来生成key对应的value
from collections import defaultdict
import random
d1 = defaultdict(list)
for k in 'abcdef':
for i in range(random.randint(1,3)):
d1[k].append(i)
print(d1)
defaultdict(<class 'list'>, {'a': [0, 1, 2], 'b': [0], 'c': [0, 1, 2], 'd': [0, 1, 2], 'e': [0, 1], 'f': [0]})
OrderdeDict
key并不是按照加入的顺序排列,可以使用OrderdeDict记录顺序
有序字典可以记录元素插入的顺序,打印的时候也是按照这个顺序输出打印。
3.6版本的python的字典就是记录Key插入的顺序(ipython不一定有效果)
四、解析式、生成器
1、标准库 datetime
对日期、时间、时间戳的处理
datetime类
类方法
today()返回本地时区当前时间的datetime对象
now(tz = None)返回当前时间的datetime对象,时间到微妙,如果tz为None,返回和today()一样
utcnow()没有时区的当前时间
fromtimesstamp(timestamp,tz =None)从一个时间戳返回一个 datetime对象
datetime对象
timestamp()返回一个到微妙的时间戳
时间戳:格林威治时间1970年1月1日0点到现在的微妙
b、datetime构造
构造方法datetime.datetime(年 ,月,日,时,分,秒,微秒)
weekday()返回星期的天,周一0,周日6
isoweekday()返回星期的天,周一1,周日7
date()返回日期date对象
time()返回时间time对象
replace()修改并返回新的时间
isocalendar()返回一个三元组(年,周数,周的天)
strftime() 将时间对象转换成字符串
d3.strftime("%Y%m%d %H:%M:%S") #将时间对象转换成字符串
'20180801 04:32:30'
"{:%Y/%m%d %H:%M:%S}".format(d3) #字符的format转换成字符串
'2018/0801 04:32:30'
d3 = datetime.datetime.strptime('08/01/2018 04:32:30','%m/%d/%Y %H:%M:%S')
d3 #拿字符串跟format构造时间对象
datetime.datetime(2018, 8, 1, 4, 32, 30)
2、解析式
(1)列表解析式
l2 = []
for i in range(10):
l2.append((i+1)**2)
等效于:[(i+1)**2 for i in range(10)]
evens = []
for i in range(10):
if i %2 == 0:
evens.append(i)
等效于:[i for i in range(10) if i % 2]
语法:
[返回值 for元素 in可迭代对象 if条件]
使用中括号[],内部是for循环,if条件语句可选
返回一个新的列表
(2)集合表达式
语法:
{返回值 for元素 in 可迭代对象 if条件}
列表解析式的中括号换成大括号{}就行了
理解返回一个集合
(3)字典解析式
语法:
{返回值 for元素 in可迭代对象 if条件}
列表解析式的中括号换成大括号{}就行了
使用key:value形式
立即返回一个字典
3、生成器表达式
(1)生成器:
可迭代对象
迭代器
语法:
(返回值 for元素 in 可迭代对象 if条件)
注:列表解析式的中括号换成小括号就行了
返回一个生成器
g=(i for i in range(10))
print(next(g))
print(next(g))
(2)跟列表解析式区别
a、计算方式
生成器表达式延迟计算,列表解析式立即计算。
b、内存占用
单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表。
生成器没有数据,内存占用极少,但是使用的时候,虽然一个个返回数据,但合起来内存占用也差不多。
c、计算速度
单看计算时间,生成器表达式耗时非常短,列表解析式耗时长。
但是生成器本身并没有返回任何值,只返回了一个生成器对象。
列表解析式构造并返回一个新的列表。
五、内建函数
1、标识id
返回对象的唯一标识,CPython返回内存地址
2、哈希 hash()
返回一个对象的哈希值
3、类型type()
返回对象的类型
4、类型转换
float() int() bin() hex() oct() bool() list() tuple() dict() set() complex() bytes() bytearray()
5、输入input()
接收用户输入,返回一个字符串
6、打印print
print(*object, sep=’ ‘,end=’\n’, file=sys.stdout, flush=False)
打印输出,默认使用空格分割,换行结尾,输出到控制台
7、对象长度len()
返回一个集合类型的元素个数
8、isinstance(obj,class_or_tuple)
判断对象obj是否属于某种类型或者元组中累出的某个类型
isinstance(True,int)
9、issubclass(cla,class_or_tuple)
判断类型cls是否是某种类型的子类或元组中累出的某个类型的子类
issubclass里都写类型
10、数值型
abs(x) x为数值
最大值max() 最小值min()
round(x) 四舍六入五取偶
pow(x,y) 等价于x**y
range(stop) 从0开始到stop-1的可迭代对象,range(star,stop[,step])从start开始到stop-1结束,补偿为step的可迭代对象
divmod(x,y) 等价于tuple(x//y,x%y)
sum(iterable[,start] )对可迭代对象的所有数值元素求和
sum(range(5),100)
110
chr(i) 给一个一定范围的整数返回对应的数字
chr(97) chr(20013)
**ord©**返回字符对应的整数
ord(“a”) ord(“中”)
str() 、repr() 、ascii()
sorted(iterable[,key][,reverse])排序
返回一个新的列表,默认升序
reverse是反转 1、有序 2、长度 降序
sorted([1,2,3]+['a'],reverse = True, key=str)
['a', 3, 2, 1]
枚举enumerate(seq, start =0)
迭代一个序列,返回索引数字和元素构成的二元组
start表示索引开始的数字,默认是0
for x,y in enumerate("abcde",100):
print(x,y)
100 a
101 b
102 c
103 d
104 e
iter()可将可迭代对象封装成迭代器
通过Next方法,迭代迭代器对象
生成器对象就是迭代器对象
i=iter((1,2,3))
next(i)
1
*拉链函数zip(iterables)
把多个迭代对象合并在一起,返回一个迭代器
将每次从不同对象中取到的元素合并成一个元组
z=zip(range(10),range(10),range(10),range(10))
next(z)
(1, 1, 1, 1)
dict(zip("abcd",range(10)))
{'a': 0, 'b': 1, 'c': 2, 'd': 3}
生成器,迭代器,惰性惰性