neir
一、列表的基本操作
二、列表的高级使用
一、列表的基本操作
1. lpush(name,values)
import redis class MyRedis(): def __enter__(self): self.conn = redis.Redis() return self.conn def __exit__(self, exc_type, exc_val, exc_tb): self.conn.close() with MyRedis() as conn: #列表操作 # 1 lpush(name,values) conn.lpush('l1',1,2,3,4,5,'lili')
2. rpush(name,value)
conn.rpush('l1','haha')
3. lpushx(name,value) rpushx(name,value)
# 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边 # conn.lpushx('l2',9)#插入不进去,因为l1不存在 # conn.lpushx('l1',9)#可以插入进去 conn.rpushx('l1', 9) # 可以插入进去
4. llen(name)
conn.lpush('l1', 1, 2, 3, 4, 5, 'lili') res=conn.llen('l1') #6 print(res)
5. linsert(name, where, refvalue, value)) 在某个位置插入值
# where :BEFORE或AFTER,大小写都行 # refvalue: lili 表示以lili为标准(不是下标索引)。如果有两个lili,那么就会插入到序号小的那里,不会再往下找了 # conn.linsert('l1','after','lili','刘亦菲') conn.linsert('l1','before','lili','baby')
6. lset(name,index,value)
# conn.lset('l1',0,'黄晓明')#把第0个位置设置成 黄晓明,注意是从0开始的 conn.lset('l1',5,'老伙计')#把第5个位置设置成老伙计,注意是从0开始的
7. lrem(name,value,num)
# 第二个参数count: # count = 0,删除列表中所有的指定值; # count=2,从前到后,删除2个; # count=-2,从后向前,删除2个 # conn.lrem('l1',0,'lili') # 把所有lqz都删除 # conn.lrem('l1',2,'lili') # 从前往后,删除2个lili conn.lrem('l1',-1,'lili') # 从后往前,删除1个lili
8. lpop(name)
# res=conn.lpop('l1') res=conn.rpop('l1') print(res)
9. lindex(name,num)
# lindex(不删除,只是索引取值) res=conn.lindex('l1',0) print(res)
10. lrange(name,start,end) # 是前闭后闭区间
# res = conn.lrange('l1', 0, 0) #返回一个值 res = conn.lrange('l1', 0, 1)#返回2个值 print(res)
11. ltrim(start,end)
res=conn.ltrim('l1',3,5) #只保留3到5之间的数据,前闭后闭 print(res)
12.rpoplpush
# rpoplpush 需要两个列表 # conn.lpush('l1',1,2,3) # conn.lpush('l2',4,5,6) #把l1的最后一个pop出来放到l1里第一个位置 conn.rpoplpush('l1','l1') # 把l1的最后一个pop出来放到l2里 conn.rpoplpush('l1','l2')
13.blpop #block阻塞 左边弹出
# res=conn.blpop('l1') # print(res)
小应用:
rpc:是远程过程调用
14. blpoprpush
****总结
lpush llen linsert lset lrem lpop lrange # 使用它,自定义增量迭代 blpop
二、列表的高级使用
1. lrange
redis类库中没有提供对列表元素的增量迭代,借助lrange
# res=conn.lrange('l2',0,9999) # 全部取出来 # res=conn.lrange('l2',0,conn.llen('l2')) # 从0取到列表长度
lrange类似于字典的hgetall,一次性全取出来,存在的问题是,因为不知道列表有多大,很有可能撑爆内存
解决办法:增量迭代
#制造1000条数据 for i in range(1000): conn.lpush('l_test','test_%s'%i) #原来的方式: # res=conn.lrange('l3',0,conn.llen('l3')) # print(res)#一次性取出来会占用很大内存,可能撑爆 # res = conn.lrange('l_test', 0, 9) # print(res) #lscan_iter方式一: # def lscan_iter(name, conn, count=10): # cursor = 0 # lenght = conn.llen(name) # 计算列表总长度 # while cursor < lenght: # data = conn.lrange(name, cursor, (cursor+count) - 1) # cursor += count # # for item in data: # yield item # for i in lscan_iter('l_test',conn,20): # print(i) #lscan_iter方式二: def lscan_iter(name, conn, count=10): cursor = 0 while True: data = conn.lrange(name, cursor, (cursor + count) - 1) if data: cursor += count for item in data: yield item else: break for i in lscan_iter('l_test',conn,20): print(i)
三、redis其他操作
增加key,可以为以下5种类型
import redis class MyRedis(): def __enter__(self): self.conn = redis.Redis() return self.conn def __exit__(self, exc_type, exc_val, exc_tb): self.conn.close() with MyRedis() as conn: ## 公共操作 # 如果搭建哨兵。用了集群,这个模块就不够用了 # delete # res=conn.delete('l2','name')#删l2不管name是否存在 # res=conn.delete('l1','name')#删l1不管name是否存在 # exists # res=conn.exists('l1','l_test','l2') #打印1 说明只有一个存在 # res=conn.exists('l_test')#打印1 说明l_test存在 # print(res) # expire # res=conn.expire('l_test',5) #5秒后删除l_test # print(res) # rename # conn.lpush('l1',1,2,3) # res=conn.rename('l1','l2') #重命名位l2 # res=conn.move('l2',3) #把l2移到db3下 ## redis的库是隔离的 # res=conn.lpop('l2') # print(res) #None 如果要获取db3下的l2,那就要先切换到db3库 # 随机出一个key值 # conn.lpush('l1', 1, 2, 3) # conn.lpush('l2', 1, 2, 3) # conn.lpush('l3', 1, 2, 3) # res=conn.randomkey() # print(res) #随机获取key值 # # 应用:利用redis随机抽奖 # conn.sadd('choujiang',9) # conn.sadd('choujiang',90) # conn.sadd('choujiang',99) # res = conn.spop('choujiang') # print(res) # type----查看类型 # res=conn.type('choujiang') #b'set' # res=conn.type('ss') #b'string' res = conn.type('zzz')#b'zset' print(res)
四、redis通过管道实现事务
### redis是数据库,非关系型数据库,不支持事务 ## redis提供了管道,通过管道,实现事务 注意:在mysql中通过混滚实现事务 # 开启一个管道 pi = conn.pipeline(transaction=True) pi.multi() #用于批量实现业务 # 只要人的年龄加了1,工资加1w pi.incr('age') raise Exception('出异常了') pi.incr('salary', 10000) # 向管道中发送了两个命令,并没有真正的执行 pi.execute() # 表示一次性执行管道中的命令,抛异常后年龄不加,薪资不加,实现事务 # ## 原来操作--抛异常后,年龄增加,薪资不加 # conn.incr('age') # raise Exception('出错误了') # conn.incr('salary',1000)