Python聊天机器人中使用pairs调用打印函数时出现ValueError
解决NLTK Chat机器人pairs配置的ValueError问题
这个报错的根源很明确:你给pairs列表里的第一个条目塞了三个元素,但NLTK的Chat类要求每个配对必须是两个元素的结构(匹配模式 + 响应内容/逻辑),所以初始化时才会抛出too many values to unpack (expected 2)的错误。
错误原因拆解
你的原代码里,第一个配对是这样的:
['i want to see reports', ['In which subject area would you like to see the reports?'],listSubjectArea()]
这是一个包含3个元素的列表,但Chat类在解析pairs时,期望每个条目都是(匹配正则, 响应列表/可调用对象)的二元组(或列表)。它会尝试把每个条目拆成x和y两个值,你的条目有三个元素,自然就解包失败了。
修复方案
要实现触发问题时打印科目列表的需求,我们需要把listSubjectArea()的逻辑整合到响应里,有两种常用方式:
方式1:让函数返回格式化的科目列表文本
修改listSubjectArea(),让它返回拼接好的字符串,而不是直接打印,然后把这个字符串和提示文本合并到响应里:
def listSubjectArea(): # 用enumerate更简洁地生成带序号的科目列表 subject_lines = [f"{idx}. {subject}" for idx, subject in enumerate(subjectAreaList, 1)] return "\n".join(subject_lines) # 修正后的pairs第一个条目 pairs = [ ['i want to see reports', ['In which subject area would you like to see the reports?\n' + listSubjectArea()]], ['subject1(.*)', ['blah blah blah']], ['subject2(.*)', ['blah blah blah']], ['subject3(.*)', ['blah blah blah']] ]
方式2:用可调用函数作为响应(保留直接打印的逻辑)
如果你希望保持函数直接打印到控制台的逻辑,可以把响应设为一个自定义函数,NLTK允许响应是无参数且返回字符串的可调用对象:
def handle_report_query(): # 直接打印科目列表 for idx, subject in enumerate(subjectAreaList, 1): print(f"{idx}. {subject}") # 返回机器人的提示文本 return "In which subject area would you like to see the reports?" # 修正后的pairs第一个条目 pairs = [ ['i want to see reports', handle_report_query], ['subject1(.*)', ['blah blah blah']], ['subject2(.*)', ['blah blah blah']], ['subject3(.*)', ['blah blah blah']] ]
完整修复后的代码示例(方式1)
from nltk.chat.util import Chat, reflections import re subjectAreaList = ["subject1","subject2","subject3"] def listSubjectArea(): subject_lines = [f"{idx}. {subject}" for idx, subject in enumerate(subjectAreaList, 1)] return "\n".join(subject_lines) pairs = [ ['i want to see reports', ['In which subject area would you like to see the reports?\n' + listSubjectArea()]], ['subject1(.*)', ['blah blah blah']], ['subject2(.*)', ['blah blah blah']], ['subject3(.*)', ['blah blah blah']] ] reflections = { 'i am' : 'you are', 'i was' : 'you were', 'i': 'you' } chat = Chat(pairs, reflections) print("Hi,What do you want to do ?") chat.converse(quit='by')
这样修改后,当用户输入i want to see reports时,机器人会先输出提示文本,紧接着打印带序号的科目列表,完全符合你的需求。
内容的提问来源于stack exchange,提问作者user12689308
相关产品推荐
相关产品推荐

