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

Python实现手机号单位置字符替换生成变体的问题求解

问题描述

我想要编写一个Python函数,接收字符串格式的手机号,生成所有仅单个字符按指定规则替换后的排列组合。例如手机号为9879876时,需返回8879876、6879876、9579876等变体。

我尝试使用str.replace方法替换字符,但该方法会替换所有匹配的字符,即使使用count参数也无法仅替换指定位置的目标字符。以下是替换规则:

rep1 = ["2","4"]
rep2 = ["1","3","5"]
rep3 = ["2","6"]
rep4 = ["1","5","7"]
rep5 = ["2","4","6","8"]
rep6 = ["3","5","9"]
rep7 = ["4","8"]
rep8 = ["5","7","9","0"]
rep9 = ["6","8"]
rep0 = ["8"]

即若当前遍历到的数字是1,则将该位置的1替换为rep1中的每个字符,其余部分保持不变;数字为2时替换为rep2中的每个字符,以此类推。我编写的代码如下,但未能实现需求,希望得到更优雅的解决方案:

def myfunc(phone:str):
    for digit in phone:
        if digit == "1":
            newphone = phone.replace("1", "2", 1)
            print(newphone)
            newphone = phone.replace("1", "4",1)
            print(newphone)
        if digit == "2":
            newphone = phone.replace("2", "1",1)
            print(newphone)
            newphone = phone.replace("2", "3",1)
            print(newphone)
            newphone = phone.replace("2", "5",1)
            print(newphone)
        if digit == "3":
            newphone = phone.replace("3", "2",1)
            print(newphone)
            newphone = phone.replace("3", "6",1)
            print(newphone)
        if digit == "4":
            newphone = phone.replace("4", "1",1)
            print(newphone)
            newphone = phone.replace("4", "5",1)
            print(newphone)
            newphone = phone.replace("4", "7",1)
            print(newphone)
        if digit == "5":
            newphone = phone.replace("5", "2",1)
            print(newphone)
            newphone = phone.replace("5", "4",1)
            print(newphone)
            newphone = phone.replace("5", "6",1)
            print(newphone)
            newphone = phone.replace("5", "8",1)
            print(newphone)
        if digit == "6":
            newphone = phone.replace("6", "3",1)
            print(newphone)
            newphone = phone.replace("6", "5",1)
            print(newphone)
            newphone = phone.replace("6", "9",1)
            print(newphone)
        if digit == "7":
            newphone = phone.replace("7", "4",1)
            print(newphone)
            newphone = phone.replace("7", "8",1)
            print(newphone)
        if digit == "8":
            newphone = phone.replace("8", "5",1)
            print(newphone)
            newphone = phone.replace("8", "7",1)
            print(newphone)
            newphone = phone.replace("8", "9",1)
            print(newphone)
            newphone = phone.replace("8", "0",1)
            print(newphone)
        if digit == "9":
            newphone = phone.replace("9", "6",1)
            print(newphone)
            newphone = phone.replace("9", "8",1)
            print(newphone)
        if digit == "0":
            newphone = phone.replace("0", "8",1)
            print(newphone)
解决方案

问题根源

原代码使用str.replace(digit, replacement, 1)时,每次都会替换第一个出现的目标字符,而非当前遍历到的位置的字符。比如手机号是9879876,遍历到第二个9时,replace("9", "6", 1)还是会替换第一个9,导致生成错误的变体。

优化思路

  1. 将替换规则整理为字典,用原数字作为键,替换列表作为值,消除大量重复的if判断,简化代码。
  2. 遍历手机号时记录每个字符的索引位置,通过字符串切片拼接的方式,精确替换指定位置的字符。

优化后的代码

def generate_phone_variants(phone: str) -> list[str]:
    # 整理替换规则为字典,便于快速查找
    replace_rules = {
        "1": ["2", "4"],
        "2": ["1", "3", "5"],
        "3": ["2", "6"],
        "4": ["1", "5", "7"],
        "5": ["2", "4", "6", "8"],
        "6": ["3", "5", "9"],
        "7": ["4", "8"],
        "8": ["5", "7", "9", "0"],
        "9": ["6", "8"],
        "0": ["8"]
    }
    
    variants = []
    # 同时遍历字符索引和值,准确定位替换位置
    for idx, digit in enumerate(phone):
        # 获取当前数字对应的替换列表,无匹配则返回空列表
        replacements = replace_rules.get(digit, [])
        for rep in replacements:
            # 通过切片拼接生成新手机号:前半段 + 替换字符 + 后半段
            new_phone = phone[:idx] + rep + phone[idx+1:]
            variants.append(new_phone)
    return variants

# 示例调用
if __name__ == "__main__":
    phone = "9879876"
    variants = generate_phone_variants(phone)
    for variant in variants:
        print(variant)

代码说明

  • 使用enumerate同时获取字符的索引和值,确保替换的是当前遍历到的位置的字符。
  • 字符串切片phone[:idx]和phone[idx+1:]分别截取目标位置前后的部分,中间拼接替换字符,实现精确替换。
  • 替换规则用字典存储,后续修改规则只需调整字典内容,维护更方便。
  • 函数返回变体列表而非直接打印,提升了代码的复用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:30:56