You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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为空的原因

  1. Redis哈希表无数据:首次运行游戏时,2048哈希表还未存储任何分数,r.hgetall('2048')返回空字典,对应的values()集合为空,最终生成的scores就是空列表。
  2. Redis连接异常:代码未做连接异常捕获,若IP、端口、密码错误或网络不通,可能导致Redis客户端返回空结果;若权限不足,也会获取不到数据。
  3. 哈希表键名错误:实际存储分数时使用的键名不是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:01:08