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

Python代码第三次调用输出错误,请求问题排查与修正

Python超级英雄名字生成器Bug排查

我正在学习Python的MOOC课程,这是第一次提问。我的代码预期输出应为:

Captain Hawk
Doctor Yellow Jacket
Moon Moon

但实际输出是:

Captain Hawk
Doctor Yellow Jacket
Moon Yellow Jacket

请帮忙排查代码和heronames.txt文件中的问题。

原代码

#A common meme on social media is the name generator. These
#are usually images where they map letters, months, days,
#etc. to parts of fictional names, and then based on your
#own name, birthday, etc., you determine your own.
#
#For example, here's one such image for "What's your
#superhero name?": https://i.imgur.com/TogK8id.png
#
#Write a function called generate_name. generate_name should
#have two parameters, both strings. The first string will
#represent a filename from which to read name parts. The
#second string will represent an individual person's name,
#which will always be a first and last name separate by a
#space.
#
#The file with always contain 52 lines. The first 26 lines
#are the words that map to the letters A through Z in order
#for the person's first name, and the last 26 lines are the
#words that map to the letters A through Z in order for the
#person's last name.
#
#Your function should return the person's name according to
#the names in the file.
#
#For example, take a look at the names in heronames.txt
#(look in the drop-down in the top left). If we were to call
#generate_name("heronames.txt", "Addison Zook"), then the
#function would return "Captain Hawk": Line 1 would map to
#"A", which is the first letter of Addison's first name, and
#line 52 would map to "Z", which is the first letter of
#Addison's last name. The contents of those lines are
#"Captain" and "Hawk", so the function returns "Captain Hawk".
#
#You should assume the contents of the file will change when
#the autograder runs your code. You should NOT assume
#that every name will appear only once. You may assume that
#both the first and last name will always be capitalized.
#
#HINT: Use chr() to convert an integer to a character.
#chr(65) returns "A", chr(90) returns "Z".


#Add your code here!

def generate_name(filename, name):    
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    # splitting the name so I can add the intials of the name into a list.
    z = []
    j = name.split()
    for i in j:
        z.append(i[0])
    
    # linking the initials to it's index in the alphabet  
    for k in alphabet:
        if k == z[0]:
            first = alphabet.index(k)
        elif k == z[1]:
            second = alphabet.index(k) + 26
        else:
            pass
        
        
    # reading the super hero names from the file and linking the name to the index   
    file = open(filename, "r") 
    filelist = file.readlines()

    for i in filelist:
        global hero
        if filelist.index(i) == first:
            supe = i
            supe = supe.strip()
        elif filelist.index(i) == second:
            hero = i
            hero = hero.strip()
        else:
            pass
    
    file.close()
    return supe + " " + hero
        
       
#Below are some lines of code that will test your function.
#You can change the value of the variable(s) to test your
#function with different inputs.
#
#If your function works correctly, this will originally
#print: Captain Hawk, Doctor Yellow Jacket, and Moon Moon,
#each on their own line.
print(generate_name("heronames.txt", "Addison Zook"))
print(generate_name("heronames.txt", "Uma Irwin"))
print(generate_name("heronames.txt", "David Joyner"))

heronames.txt内容

Captain
Night
Ancident
Moon
Spider
Invisible
Silver
Dark
Professor
Golden
Radioactive
Incredible
Impossible
Iron
Rocket
Power
Green
Super
Wonder
Metal
Doctor
Masked
Crimson
Omega
Lord
Sun
Lightning
Knight
Hulk
Centurion
Surfer
Warriors
Ghost
Hornet
Yellow Jacket
Moon
Ghost
Phantom
Machine
X
Doom
Z
Fist
Shadow
Claw
Torch
Soldier
Skull
Thunder
Hurricane
Falcon
Hawk

问题根源分析

  1. 全局变量导致状态残留
    使用global hero会让变量在函数多次调用之间保留值。第三次调用generate_name("heronames.txt", "David Joyner")时,若未成功匹配到目标索引,hero会保留上一次调用(Uma Irwin)的结果Yellow Jacket。

  2. list.index()逻辑错误
    filelist.index(i)返回的是列表中第一个匹配元素的索引,而非当前遍历元素的索引。例如heronames.txt中第4行和第35行都是Moon,遍历到第35行时,index()会返回4而非35,导致filelist.index(i) == second(此时second=35)的条件永远不成立,无法更新hero的值。

  3. 索引计算效率低下
    遍历字母表找首字母索引的方式冗余,直接用ord()函数计算更高效。


修正后的代码

def generate_name(filename, name):    
    # 分割名字获取首字母
    first_name, last_name = name.split()
    first_initial = first_name[0]
    last_initial = last_name[0]
    
    # 计算对应的索引:首字母对应0-25,姓氏对应26-51
    first_index = ord(first_initial) - ord('A')
    last_index = ord(last_initial) - ord('A') + 26
    
    # 读取文件内容并预处理换行符
    with open(filename, "r") as file:
        filelist = [line.strip() for line in file.readlines()]
    
    # 直接通过索引获取对应名字
    supe_part = filelist[first_index]
    hero_part = filelist[last_index]
    
    return f"{supe_part} {hero_part}"


# 测试代码
print(generate_name("heronames.txt", "Addison Zook"))
print(generate_name("heronames.txt", "Uma Irwin"))
print(generate_name("heronames.txt", "David Joyner"))

修正说明

  • 移除全局变量,每次调用重新生成结果,避免状态残留
  • 用ord()直接计算首字母索引,无需遍历字母表
  • 直接通过索引访问列表元素,彻底规避list.index()的匹配问题
  • 使用with语句管理文件,自动关闭更安全
  • 读取文件时直接处理换行符,减少重复操作

内容的提问来源于stack exchange,提问作者mirror1023

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:46:09