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

Python改写CSV文件后行索引混乱问题求助

解决删除联系人后行索引混乱的问题

你的问题核心大概率出在删除后写入CSV文件时未正确处理换行符,或是读写过程中引入了空行,导致后续统计行数、定位联系人时出现索引偏差。结合你给出的现有代码,还有几个细节问题会加剧这个混乱,咱们一步步来修复:

问题根源拆解

  1. CSV写入的换行符隐患:如果用csv.writer写入文件时没指定newline='',Windows系统下会自动在每行末尾追加额外换行符,生成空行。后续读取时这些空行被当成无效条目,直接打乱索引计数。
  2. 递归调用的逻辑风险:你的main()和view()都用递归实现循环,多次执行后容易触发栈溢出,还会让错误处理的逻辑变得混乱。
  3. 重复读文件的一致性问题:多个函数单独打开读取文件,可能因为文件状态未同步(比如删除操作还没写完),导致读取到不一致的内容。

修复后的完整代码

我重构了你的代码,解决索引问题的同时优化了整体逻辑:

import csv

# 定义全局常量统一管理文件名
CONTACTS_FILE = "contacts.csv"

def print_menu():
    print("Contact List\n")
    print(" list - Display all contacts")
    print(" view - View a contact")
    print(" add - Add a contact")
    print(" del - Delete a contact")
    print(" exit - Exit program\n")

def load_contacts():
    """统一加载所有联系人,自动跳过空行"""
    contacts = []
    with open(CONTACTS_FILE, newline='') as file:
        reader = csv.reader(file)
        for row in reader:
            if row:  # 跳过写入时可能产生的空行
                contacts.append(row)
    return contacts

def save_contacts(contacts):
    """统一保存联系人到CSV,避免换行符问题"""
    with open(CONTACTS_FILE, 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerows(contacts)

def list_contacts():
    contacts = load_contacts()
    if not contacts:
        print("No contacts found.")
        return
    # 用enumerate直接生成从1开始的索引,无需手动维护计数器
    for idx, contact in enumerate(contacts, start=1):
        print(f"{idx}. {contact[0]}")

def view_contact():
    contacts = load_contacts()
    if not contacts:
        print("No contacts to view.")
        return
    
    # 用循环做输入验证,替代递归
    while True:
        num_input = input("Enter a contact's number to view their information: ")
        if not num_input.isdigit():
            print("Invalid input, please enter a number.")
            continue
        num = int(num_input)
        if 1 <= num <= len(contacts):
            break
        print(f"Invalid input, please enter a number between 1 and {len(contacts)}.")
    
    contact = contacts[num - 1]
    print(f"Name: {contact[0]}\nEmail: {contact[1]}\nPhone Number: {contact[2]}")

def add_contact():
    name = input("Enter contact name: ").strip()
    email = input("Enter contact email: ").strip()
    phone = input("Enter contact phone number: ").strip()
    
    contacts = load_contacts()
    contacts.append([name, email, phone])
    save_contacts(contacts)
    print(f"Contact '{name}' added successfully!")

def delete_contact():
    contacts = load_contacts()
    if not contacts:
        print("No contacts to delete.")
        return
    
    # 删除前先列出联系人,方便用户选择
    list_contacts()
    while True:
        num_input = input("Enter the number of the contact to delete: ")
        if not num_input.isdigit():
            print("Invalid input, please enter a number.")
            continue
        num = int(num_input)
        if 1 <= num <= len(contacts):
            break
        print(f"Invalid input, please enter a number between 1 and {len(contacts)}.")
    
    # 弹出指定索引的联系人并保存
    deleted_name = contacts.pop(num - 1)[0]
    save_contacts(contacts)
    print(f"Contact '{deleted_name}' deleted successfully!")

def main():
    print_menu()
    # 用循环替代递归,避免栈溢出
    while True:
        command = input("\nCommand: ").strip().lower()
        if command == "list":
            list_contacts()
        elif command == "view":
            view_contact()
        elif command == "add":
            add_contact()
        elif command == "del":
            delete_contact()
        elif command == "exit":
            print("Exiting program...")
            break
        else:
            print("Invalid input, try again.")

if __name__ == "__main__":
    main()

关键修复说明

  1. 统一读写入口:load_contacts()和save_contacts()接管所有文件操作,确保每次读写的内容一致,还会自动跳过空行。
  2. 强制指定newline='':这是CSV模块官方推荐的写法,彻底解决不同系统下的换行符差异,避免空行导致的索引混乱。
  3. 循环替代递归:主程序和输入验证都用while True循环,逻辑更清晰,还能避免递归栈溢出的问题。
  4. 索引生成简化:用enumerate(contacts, start=1)直接生成从1开始的联系人序号,无需手动维护计数器,减少出错概率。
  5. 原子化删除逻辑:先一次性加载所有联系人,删除指定条目后再整体保存,整个过程不会出现索引错位。

测试建议

确保你的contacts.csv初始内容无空行,格式类似:

Alice,alice@example.com,1234567890
Bob,bob@example.com,0987654321
Charlie,charlie@example.com,5555555555
Dave,dave@example.com,7777777777

删除联系人后执行list命令,检查索引是否连续;再用view命令验证能否正确定位剩余联系人。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:44:23