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

Python字符串替换异常:多位数编号被拆分为个位数重复替换

问题描述

我在处理一份配送信息文件,每行格式为「姓名, 商品编号, 商品编号...」,示例内容:Joe, 2, 22, 10, 17。

尝试将商品编号替换为字典对应值时出现错误:编号22未被替换为对应的"Tandbørste",反而被替换成键2对应的"Snus"两次。我试过把字典的键改成字符串类型,问题仍未解决。

相关代码及测试文件内容如下:

import sys
f = open("testFil.txt", "r")
list_of_lists = []

items = {
    1: "Cigaretter",
    2: "Snus",
    3: "Kaffe",
    4: "Te",
    5: "Solbriller",
    6: "Mørk Chokolade",
    7: "Kiks",
    8: "Harebo Mix",
    9: "Salt Chips",
    10: "Pepper Chips",
    11: "Sour Cream Chips",
    12: "Oreo",
    13: "Ritter Sport",
    14: "Chokolade Kiks",
    15: "Mælk",
    16: "Sukker",
    17: "Brød",
    18: "Kuglepen",
    19: "Juice",
    20: "Avis",
    21: "Toilet Papir",
    22: "Tandbørste",
    23: "Kondomer",
    24: "Tandpasta",
    25: "Køkkenrulle"}

with open("testFil.txt", "r") as f:
    for line in f:
        line = line.replace("\n","")
        for i in items:
            line = line.replace(str(i), items[i])
        list_of_lists.append(line.split(", "))


for i in list_of_lists:
    for j in i:
        if i.count(j) > 1:
            i[i.index(j)] = str(i.count(j)) + "x " + j
            for k in range(i.count(j)):
                i.remove(j)

customer_count = -1



def last_customer():
    print("This is the last order")
    print(list_of_lists[next_customer()])

def luk_programmet():
    sys.exit()

def next_customer():
    global customer_count
    customer_count += 1
    return customer_count

def print_customer():
    a = input("")
    if a == "Next Order":
        if customer_count == len(list_of_lists) - 2:
            print("This is the last order")
            print(list_of_lists[next_customer()])
            luk_programmet()
        else:
            try:
                print(list_of_lists[next_customer()])
            except IndexError:
                print("This is the last order")
                luk_programmet()

    elif a == "/close the program":
        luk_programmet()

    else:
        print("You typed it wrong.")
        print_customer()

#Prints the customer list

print("Write 'Next Order' to recieve the next order")
for i in range(len(list_of_lists)):
    if print_customer() == "Done":
        sys.exit()
    print_customer()

测试文件testFil.txt内容:

Joe, 1, 2, 1, 8
Micky, 19, 19, 15, 13
Berta, 4, 3, 3, 3
Frede, 24, 22, 8, 2
per, 1, 9, 18, 24
错误原因

问题出在整行字符串循环替换的逻辑上:当你先把"2"替换成"Snus"后,原字符串中的"22"会被拆成两个独立的"2"。第一次替换第一个"2"得到"Snus2",后续遍历到"2"时又会替换剩余的"2",最终变成"SnusSnus"。此外,字典的遍历顺序若先处理小数字,会直接破坏大数字的结构,导致替换错误。

解决方案

正确的做法是先拆分每行内容,单独处理每个商品编号,而非直接在整行字符串上做全局替换。

步骤1:修改文件读取与编号转换逻辑

将整行替换改为拆分后逐个转换编号:

with open("testFil.txt", "r") as f:
    for line in f:
        line = line.strip("\n")
        parts = line.split(", ")
        name = parts[0]
        converted_items = []
        for num_str in parts[1:]:
            # 将字符串编号转为整数,从字典取值,取不到则保留原编号
            item_num = int(num_str)
            converted_items.append(items.get(item_num, num_str))
        list_of_lists.append([name] + converted_items)

此方式可精准处理每个编号,避免字符串替换带来的误匹配问题。

步骤2:优化重复商品统计逻辑

原统计逻辑在修改列表时会因索引变化导致遗漏,改用字典统计更可靠:

processed_list = []
for order in list_of_lists:
    name = order[0]
    item_counts = {}
    for item in order[1:]:
        item_counts[item] = item_counts.get(item, 0) + 1
    # 转换为带数量的格式
    formatted_items = [f"{count}x {item}" if count > 1 else item for item, count in item_counts.items()]
    processed_list.append([name] + formatted_items)
list_of_lists = processed_list

完整修正代码

import sys
list_of_lists = []

items = {
    1: "Cigaretter",
    2: "Snus",
    3: "Kaffe",
    4: "Te",
    5: "Solbriller",
    6: "Mørk Chokolade",
    7: "Kiks",
    8: "Harebo Mix",
    9: "Salt Chips",
    10: "Pepper Chips",
    11: "Sour Cream Chips",
    12: "Oreo",
    13: "Ritter Sport",
    14: "Chokolade Kiks",
    15: "Mælk",
    16: "Sukker",
    17: "Brød",
    18: "Kuglepen",
    19: "Juice",
    20: "Avis",
    21: "Toilet Papir",
    22: "Tandbørste",
    23: "Kondomer",
    24: "Tandpasta",
    25: "Køkkenrulle"}

# 读取并转换订单
with open("testFil.txt", "r") as f:
    for line in f:
        line = line.strip("\n")
        parts = line.split(", ")
        name = parts[0]
        converted_items = []
        for num_str in parts[1:]:
            item_num = int(num_str)
            converted_items.append(items.get(item_num, num_str))
        list_of_lists.append([name] + converted_items)

# 统计重复商品
processed_list = []
for order in list_of_lists:
    name = order[0]
    item_counts = {}
    for item in order[1:]:
        item_counts[item] = item_counts.get(item, 0) + 1
    formatted_items = [f"{count}x {item}" if count > 1 else item for item, count in item_counts.items()]
    processed_list.append([name] + formatted_items)
list_of_lists = processed_list

customer_count = -1

def luk_programmet():
    sys.exit()

def next_customer():
    global customer_count
    customer_count += 1
    return customer_count

def print_customer():
    a = input("")
    if a == "Next Order":
        if customer_count == len(list_of_lists) - 2:
            print("这是最后一份订单")
            print(list_of_lists[next_customer()])
            luk_programmet()
        else:
            try:
                print(list_of_lists[next_customer()])
            except IndexError:
                print("这是最后一份订单")
                luk_programmet()

    elif a == "/close the program":
        luk_programmet()

    else:
        print("输入错误,请重新输入。")
        print_customer()

# 启动程序
print("输入'Next Order'获取下一份订单")
for _ in range(len(list_of_lists)):
    print_customer()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:20:35