调用max()触发ValueError:空序列,求助排查Redis相关Python代码问题
解决max()空序列报错问题:Redis获取不到分数数据的原因与修复方案
问题场景
以下是用于绘制2048游戏历史最高分的Python代码:
# Plot the highest score in history def draw_best(background): ip = 'redis-16784.c89.us-east-1-3.ec2.cloud.redislabs.com' r = redis.Redis(host=ip, password=1206, port=16784, db=0, decode_responses = True) scores = [eval(i) for i in list(r.hgetall('2048').values())] best_scores = max(scores) scoreSurf = BasicFont01.render('Top score:{}'.format(best_scores), True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() scoreRect.width = math.floor((rate - 0.15) / 2 * screen.get_width()) scoreRect.height = math.floor((1 - rate2) / 3 * 2 * screen.get_height()) scoreRect.topright = (math.floor(0.9 * screen.get_width()), math.floor(0.05 * screen.get_height())) py.draw.rect(screen, background, [scoreRect.topleft[0], scoreRect.topleft[1], scoreRect.width, scoreRect.height], 0) screen.blit(scoreSurf, scoreRect)
运行时触发错误:
ValueError: max() arg is an empty sequence
问题集中在这两行代码:
scores = [eval(i) for i in list(r.hgetall('2048').values())] best_scores = max(scores)
scores为空的原因
- Redis哈希表无数据:首次运行游戏时,
2048哈希表还未存储任何分数,r.hgetall('2048')返回空字典,对应的values()集合为空,最终生成的scores就是空列表。 - Redis连接异常:代码未做连接异常捕获,若IP、端口、密码错误或网络不通,可能导致Redis客户端返回空结果;若权限不足,也会获取不到数据。
- 哈希表键名错误:实际存储分数时使用的键名不是
2048,导致无法匹配到对应数据。
修复方案
1. 排查连接与数据状态,处理空列表
添加连接校验和空值处理逻辑,避免程序崩溃:
def draw_best(background): ip = 'redis-16784.c89.us-east-1-3.ec2.cloud.redislabs.com' best_scores = 0 # 默认最高分设为0 try: r = redis.Redis(host=ip, password=1206, port=16784, db=0, decode_responses = True) r.ping() # 测试连接是否正常 hash_data = r.hgetall('2048') # 安全转换分数,替换存在风险的eval scores = [] for val in hash_data.values(): try: scores.append(int(val)) except ValueError: continue # 跳过无法转换为整数的无效数据 if scores: best_scores = max(scores) except redis.ConnectionError: print("Redis连接失败:检查IP、端口、密码或网络状态") # 后续绘制代码保持不变 scoreSurf = BasicFont01.render('Top score:{}'.format(best_scores), True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() scoreRect.width = math.floor((rate - 0.15) / 2 * screen.get_width()) scoreRect.height = math.floor((1 - rate2) / 3 * 2 * screen.get_height()) scoreRect.topright = (math.floor(0.9 * screen.get_width()), math.floor(0.05 * screen.get_height())) py.draw.rect(screen, background, [scoreRect.topleft[0], scoreRect.topleft[1], scoreRect.width, scoreRect.height], 0) screen.blit(scoreSurf, scoreRect)
2. 初始化Redis初始数据
在游戏启动逻辑中添加初始化代码,确保2048哈希表存在初始值:
# 游戏启动时执行一次 r = redis.Redis(host='redis-16784.c89.us-east-1-3.ec2.cloud.redislabs.com', password=1206, port=16784, db=0, decode_responses=True) if not r.exists('2048'): r.hset('2048', 'initial', '0') # 存入初始分数0
3. 替换eval为安全转换
eval()存在安全风险(若Redis中存入恶意代码会被执行),改用int()转换并处理异常,提升代码安全性。
内容的提问来源于stack exchange,提问作者Guanzheng Yu
相关产品推荐
相关产品推荐

