Python redis 使用(笔记)2

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Python redis 使用(笔记

4.修改(指定索引号进行修改)

r.lset(name, index, value)

对name对应的list中的某一个索引位置重新赋值

  • name - redis的name
  • index - list的索引位置
  • value - 要设置的值
r.lset("list2", 0, -11)    # 把索引号是0的元素修改成-11
print(r.lrange("list2", 0, -1))

5.删除(指定值进行删除)

r.lrem(name, count, value)

在name对应的list中删除指定的值

  • name - redis的name
  • count
  • count=0,删除列表中所有的指定值;
  • count=1,从前到后,删除左边第1个
  • count=-2,从后向前,删除2个
  • value - 要删除的值
r.lrem("list2", 1, "11")    # 将列表中左边第一次出现的"11"删除
print(r.lrange("list2", 0, -1))
r.lrem("list2", -1, "99")    # 将列表中右边第一次出现的"99"删除
print(r.lrange("list2", 0, -1))
r.lrem("list2", 0, "22")    # 将列表中所有的"22"删除
print(r.lrange("list2", 0, -1))

6.删除并返回

lpop(name)

在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素

rpop(name) 表示从右向左操作
r.lpop("list2")    # 删除列表最左边的元素,并且返回删除的元素
print(r.lrange("list2", 0, -1))
print(r.rpop("list2"))    # 删除列表最右边的元素,并且返回删除的元素
print(r.lrange("list2", 0, -1))

7.删除索引之外的值

ltrim(name, start, end)

在name对应的列表中移除没有在start-end索引之间的值

  • name - redis的name
  • start - 索引的起始位置
  • end - 索引结束位置
r.ltrim("list2", 0, 2)    # 删除索引号是0-2之外的元素,值保留索引号是0-2的元素
print(r.lrange("list2", 0, -1))

8.取值(根据索引号取值)

lindex(name, index)

在name对应的列表中根据索引获取列表元素

print(r.lindex("list2", 0))  # 取出索引号是0的值
print(type(r.lindex("list2", 0)))
# 输出结果
00
<class 'str'>

9.移动 元素从一个列表移动到另外一个列表

rpoplpush(src, dst)

从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边

  • src - 要取数据的列表的 name
  • dst - 要添加数据的列表的 name
r.rpoplpush("list1", "list2")
print(r.lrange("list2", 0, -1))

10.移动 元素从一个列表移动到另外一个列表 可以设置超时

brpoplpush(src, dst, timeout=0)

从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧

  • src - 取出并要移除元素的列表对应的name
  • dst - 要插入元素的列表对应的name
  • timeout - 当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞
r.brpoplpush("list1", "list2", timeout=2)
print(r.lrange("list2", 0, -1))

11.一次移除多个列表

blpop(keys, timeout)

将多个列表排列,按照从左到右去pop对应列表的元素

  • keys - redis的name的集合
  • timeout - 超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞

r.brpop(keys, timeout) 同 blpop,将多个列表排列,按照从右像左去移除各个列表内的元素

r.lpush("list10", 3, 4, 5)
r.lpush("list11", 3, 4, 5)
while True:
    r.blpop(["list10", "list11"], timeout=2)
    print(r.lrange("list10", 0, -1), r.lrange("list11", 0, -1))

12.自定义增量迭代

由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要获取name对应的所有列表。

循环列表

但是,如果列表非常大,那么就有可能在第一步时就将程序的内容撑爆,所以有必要自定义一个增量迭代的功能:

def list_iter(name):
    """
    自定义redis列表增量迭代
    :param name: redis中的name,即:迭代name对应的列表
    :return: yield 返回 列表元素
    """
    list_count = r.llen(name)
    for index in range(list_count):
        yield r.lindex(name, index)
# 使用
for item in list_iter('list2'): # 遍历这个列表
    print(item)

6、redis基本命令 set

1.新增

sadd(name,values)
  • name - 对应的集合中添加元素
r.sadd("set1", 33, 44, 55, 66)  # 往集合中添加元素
print(r.scard("set1"))  # 集合的长度是4
print(r.smembers("set1"))   # 获取集合中所有的成员
# 输出结果
4
{'66', '55', '33', '44'}

2.获取元素个数 类似于len

scard(name)

获取name对应的集合中元素个数

3.获取集合中所有的成员

获取name对应的集合的所有成员

smembers(name)

获取集合中所有的成员–元组形式

sscan(name, cursor=0, match=None, count=None)
print(r.sscan("set1"))
# 输出结果
(0, ['33', '44', '55', '66'])

获取集合中所有的成员–迭代器的方式

sscan_iter(name, match=None, count=None)

同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大

for i in r.sscan_iter("set1"):
    print(i)
# 输出结果
33
44
55
66

4.差集

sdiff(keys, *args)

在第一个name对应的集合中且不在其他name对应的集合的元素集合

r.sadd("set2", 11, 22, 33)
print(r.smembers("set1"))   # 获取集合中所有的成员
print(r.smembers("set2"))
print(r.sdiff("set1", "set2"))   # 在集合set1但是不在集合set2中
print(r.sdiff("set2", "set1"))   # 在集合set2但是不在集合set1中

差集–差集存在一个新的集合中

sdiffstore(dest, keys, *args)

获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中,返回值为新集合中键的数目。

print(r.sdiffstore("set3", "set1", "set2"))   # 在集合set1但是不在集合set2中
print(r.smembers("set3"))   # 获取集合3中所有的成员
# 输出结果
3
{'66', '44', '55'} #无序

5.交集

sinter(keys, *args)

获取多一个name对应集合的交集

print(r.sinter("set1", "set2")) # 取2个集合的交集

交集–交集存在一个新的集合中,返回值为新集合中键的数目。

sinterstore(dest, keys, *args)

获取多一个name对应集合的并集,再将其加入到dest对应的集合中

print(r.sinterstore("set3", "set1", "set2")) # 取2个集合的交集
print(r.smembers("set3"))
# 输出结果
6
{'55', '33', '22', '44', '66', '11'}

6.并集

sunion(keys, *args)

获取多个name对应的集合的并集,返回值为新集合中键的数目。

print(r.sunion("set1", "set2")) # 取2个集合的并集
# 输出结果
{'44', '66', '55', '33', '22', '11'}

并集–并集存在一个新的集合

sunionstore(dest,keys, *args)

获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中

print(r.sunionstore("set3", "set1", "set2")) # 取2个集合的并集
print(r.smembers("set3"))
# 输出结果
3
{'55', '66', '44'}

8.判断是否是集合的成员 类似in

sismember(name, value)

检查value是否是name对应的集合的成员,结果为True和False

print(r.sismember("set1", 33))  # 33是集合的成员
print(r.sismember("set1", 23))  # 23不是集合的成员

9.移动

smove(src, dst, value)

将某个成员从一个集合中移动到另外一个集合

r.smove("set1", "set2", 44)
print(r.smembers("set1"))
print(r.smembers("set2"))
# 输出结果
{'55', '33', '66'}
{'11', '33', '44', '22'}

10.删除–随机删除并且返回被删除值

spop(name)

从集合移除一个成员,并将其返回,说明一下,集合是无序的,所有是随机删除的

print(r.spop("set2"))   # 这个删除的值是随机删除的,集合是无序的
print(r.smembers("set2"))

11.删除–指定值删除

srem(name, values)

在name对应的集合中删除某些值

print(r.srem("set2", 11))   # 从集合中删除指定值 11
print(r.smembers("set2"))

7、redis基本命令 有序set

Set操作,Set集合就是不允许重复的列表,本身是无序的。

有序集合,在集合的基础上,为每个元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。

1.新增

zadd(name, mapping, nx=False, xx=False, ch=False, incr=False, gt=None, lt=None)

在name对应的有序集合中添加元素

import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.zadd("zset1", {"n1": 11, "n2": 22})
r.zadd("zset2", {'m1': 22, 'm2': 44})
print(r.zcard("zset1")) # 集合长度
print(r.zcard("zset2")) # 集合长度
print(r.zrange("zset1", 0, -1))   # 获取有序集合中所有元素
print(r.zrange("zset2", 0, -1, withscores=True))   # 获取有序集合中所有元素和分数
# 输出结果
2
2
['n1', 'n2']
[('m1', 22.0), ('m2', 44.0)]

2.获取有序集合元素个数 类似于len

zcard(name)

获取name对应的有序集合元素的数量

3.获取有序集合的所有元素

r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

按照索引范围获取name对应的有序集合的元素

  • name - redis的name
  • start - 有序集合索引起始位置(非分数)
  • end - 有序集合索引结束位置(非分数)
  • desc - 排序规则,默认按照分数从小到大排序
  • withscores - 是否获取元素的分数,默认只获取元素的值
  • score_cast_func - 对分数进行数据转换的函数

3-1 从大到小排序(同zrange,集合是从大到小排序的)

zrevrange(name, start, end, withscores=False, score_cast_func=float)
print(r.zrevrange("zset1", 0, -1))    # 只获取元素,不显示分数
print(r.zrevrange("zset1", 0, -1, withscores=True)) # 获取有序集合中所有元素和分数,分数倒序

3-2 按照分数范围获取name对应的有序集合的元素

zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
for i in range(1, 30):
    element = 'n' + str(i)
    r.zadd("zset3", {element: i})
print(r.zrangebyscore("zset3", 15, 25))  # # 在分数是15-25之间,取出符合条件的元素
print(r.zrangebyscore("zset3", 12, 22, withscores=True))  # 在分数是12-22之间,取出符合条件的元素(带分数)
# 输出结果
['n15', 'n16', 'n17', 'n18', 'n19', 'n20', 'n21', 'n22', 'n23', 'n24', 'n25']
[('n12', 12.0), ('n13', 13.0), ('n14', 14.0), ('n15', 15.0), ('n16', 16.0), ('n17', 17.0), ('n18', 18.0), ('n19', 19.0), ('n20', 20.0), ('n21', 21.0), ('n22', 22.0)]

3-3 按照分数范围获取有序集合的元素并排序(默认从大到小排序)

zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
print(r.zrevrangebyscore("zset3", 22, 11, withscores=True)) # 在分数是22-11之间,取出符合条件的元素 按照分数倒序

3-4 获取所有元素–默认按照分数顺序排序

zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
print(r.zscan("zset3"))
# 输出结果
(0, [('n1', 1.0), ('n2', 2.0), ('n3', 3.0), ('n4', 4.0), ('n5', 5.0), ('n6', 6.0), ('n7', 7.0), ('n8', 8.0), ('n9', 9.0), ('n10', 10.0), ('n11', 11.0), ('n12', 12.0), ('n13', 13.0), ('n14', 14.0), ('n15', 15.0), ('n16', 16.0), ('n17', 17.0), ('n18', 18.0), ('n19', 19.0), ('n20', 20.0), ('n21', 21.0), ('n22', 22.0), ('n23', 23.0), ('n24', 24.0), ('n25', 25.0), ('n26', 26.0), ('n27', 27.0), ('n28', 28.0), ('n29', 29.0)])

3-5 获取所有元素–迭代器

zscan_iter(name, match=None, count=None,score_cast_func=float)
for i in r.zscan_iter("zset3"): # 遍历迭代器
    print(i)

4.zcount(name, min, max)

获取name对应的有序集合中分数 在 [min,max] 之间的个数

print(r.zrange("zset3", 0, -1, withscores=True))
print(r.zcount("zset3", 11, 22))

5.获取值的索引号

zrank(name, value)

获取某个值在 name对应的有序集合中的索引(从 0 开始)

zrevrank(name, value),从大到小排序。
print(r.zrange("zset3", 0, -1))
print(r.zrank("zset3", "n1"))   # n1的索引号是0 这里按照分数顺序(从小到大)
print(r.zrank("zset3", "n6"))   # n6的索引号是5
print(r.zrevrank("zset3", "n1"))    # n1的索引号是28 这里安照分数倒序(从大到小)
# 输出结果
['n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11', 'n12', 'n13', 'n14', 'n15', 'n16', 'n17', 'n18', 'n19', 'n20', 'n21', 'n22', 'n23', 'n24', 'n25', 'n26', 'n27', 'n28', 'n29']
0
5
28

6.删除–指定值删除

zrem(name, values)

删除name对应的有序集合中值是values的成员

r.zrem("zset3", "n3")   # 删除有序集合中的元素n3 删除单个
print(r.zrange("zset3", 0, -1))

7.删除–根据排行范围删除,按照索引号来删除

zremrangebyrank(name, min, max)

根据排行范围删除

r.zremrangebyrank("zset3", 0, 1)  # 删除有序集合中的索引号是0, 1的元素
print(r.zrange("zset3", 0, -1))

8.删除–根据分数范围删除

zremrangebyscore(name, min, max)

根据分数范围删除

r.zremrangebyscore("zset3", 11, 22)   # 删除有序集合中的分数是11-22的元素
print(r.zrange("zset3", 0, -1))

9.获取值对应的分数

zscore(name, value)

获取name对应有序集合中 value 对应的分数

print(r.zscore("zset3", "n27"))   # 获取元素n27对应的分数27

8、其他常用操作

1.删除

delete(*names)

根据删除redis中的任意数据类型(string、hash、list、set、有序set)

r.delete("gender")  # 删除key为gender的键值对

2.检查名字是否存在

exists(name)

检测redis的name是否存在,存在就是True,False 不存在

print(r.exists("zset1"))

3.模糊匹配

keys(pattern='')

根据模型获取redis的name

KEYS * 匹配数据库中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS hllo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
print(r.keys("foo*"))

4.设置超时时间

expire(name ,time)

为某个redis的某个name设置超时时间

r.lpush("list5", 11, 22)
r.expire("list5", time=3)
print(r.lrange("list5", 0, -1))
time.sleep(3)
print(r.lrange("list5", 0, -1))

5.重命名

rename(src, dst)

对redis的name重命名

r.lpush("list5", 11, 22)
r.rename("list5", "list5-1")

6.随机获取name

randomkey()

随机获取一个redis的name(不删除)

print(r.randomkey())

7.获取类型

type(name)

获取name对应值的类型

print(r.type("set1"))
print(r.type("hash2"))
# 输出结果
set
hash

8.查看所有元素

r.scan(cursor=0, match=None, count=None)
print(r.hscan("hash2"))
print(r.sscan("set3"))
print(r.zscan("zset2"))
print(r.getrange("foo1", 0, -1))
print(r.lrange("list2", 0, -1))
print(r.smembers("set3"))
print(r.zrange("zset3", 0, -1))
print(r.hgetall("hash1"))
# 输出结果
(0, {'k2': 'v2', 'k3': 'v3'})
(0, ['44', '55', '66'])
(0, [('m1', 22.0), ('m2', 44.0)])
125.5
['22', '11', '00']
{'55', '44', '66'}
['n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n23', 'n24', 'n25', 'n26', 'n27', 'n28', 'n29']
{'k2': 'v222', 'k11': 'v1', 'k3': '123', 'k4': '1', 'k5': '-0.5', 'k6': '-6'}

9.查看所有元素–迭代器

r.scan_iter(match=None, count=None)
for i in r.hscan_iter("hash1"):
    print(i)
for i in r.sscan_iter("set3"):
    print(i)
for i in r.zscan_iter("zset3"):
    print(i)

other 方法

print(r.get('name'))    # 查询key为name的值
r.delete("gender")  # 删除key为gender的键值对
print(r.keys()) # 查询所有的Key
print(r.dbsize())   # 当前redis包含多少条数据
# r.save()    # 执行"检查点"操作,将数据写回磁盘。保存时阻塞
# r.flushdb()        # 清空r中的所有数据

管道(pipeline)

redis默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。

管道(pipeline)是redis在提供单个请求中缓冲多条服务器命令的基类的子类。它通过减少服务器-客户端之间反复的TCP数据库包,从而大大提高了执行批量命令的功能。

import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)    # 默认的情况下,管道里执行的命令可以保证执行的原子性,执行pipe = r.pipeline(transaction=False)可以禁用这一特性。
# pipe = r.pipeline(transaction=True)
pipe = r.pipeline() # 创建一个管道
pipe.set('name', 'jack')
pipe.set('role', 'sb')
pipe.sadd('faz', 'baz')
pipe.incr('num')    # 如果num不存在则vaule为1,如果存在,则value自增1
pipe.execute()
print(r.get("name"))
print(r.get("role"))
print(r.get("num"))
# 输出结果
jack
sb
3

管道的命令可以写在一起,如:

pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute()
print(r.get("name"))
print(r.get("role"))
print(r.get("num"))
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
NoSQL Unix 网络安全
【Azure Cache for Redis】Python Django-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
【Azure Cache for Redis】Python Django-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
【Azure Cache for Redis】Python Django-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
|
2月前
|
搜索推荐 Python
Leecode 101刷题笔记之第五章:和你一起你轻松刷题(Python)
这篇文章是关于LeetCode第101章的刷题笔记,涵盖了多种排序算法的Python实现和两个中等难度的编程练习题的解法。
23 3
|
2月前
|
存储 开发工具 Python
【Python项目】外星人入侵项目笔记
【Python项目】外星人入侵项目笔记
43 3
|
2月前
|
存储 Python
【免费分享编程笔记】Python学习笔记(二)
【免费分享编程笔记】Python学习笔记(二)
44 0
【免费分享编程笔记】Python学习笔记(二)
|
3月前
|
NoSQL Linux Redis
linux安装单机版redis详细步骤,及python连接redis案例
这篇文章提供了在Linux系统中安装单机版Redis的详细步骤,并展示了如何配置Redis为systemctl启动,以及使用Python连接Redis进行数据操作的案例。
79 2
|
2月前
|
算法 C++ Python
Leecode 101刷题笔记之第四章:和你一起你轻松刷题(Python)
这篇博客是关于LeetCode上使用Python语言解决二分查找问题的刷题笔记,涵盖了从基础到进阶难度的多个题目及其解法。
18 0
|
2月前
|
算法 C++ Python
Leecode 101刷题笔记之第三章:和你一起你轻松刷题(Python)
本文是关于LeetCode算法题的刷题笔记,主要介绍了使用双指针技术解决的一系列算法问题,包括Two Sum II、Merge Sorted Array、Linked List Cycle II等,并提供了详细的题解和Python代码实现。
15 0
|
2月前
|
算法 C++ 索引
Leecode 101刷题笔记之第二章:和你一起你轻松刷题(Python)
本文是关于LeetCode 101刷题笔记的第二章,主要介绍了使用Python解决贪心算法题目的方法和实例。
11 0
|
2月前
|
并行计算 Python
Python错误笔记(一):CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up env
这篇文章讨论了CUDA初始化时出现的未知错误及其解决方案,包括重启系统和安装nvidia-modprobe。
156 0
|
2月前
|
消息中间件 存储 NoSQL
python 使用redis实现支持优先级的消息队列详细说明和代码
python 使用redis实现支持优先级的消息队列详细说明和代码
38 0