哈希表

哈希表

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}

生成器,迭代器,惰性惰性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值