在Python中根据字符变化进行拆分

4 投票
3 回答
4783 浏览
提问于 2025-04-18 03:59

我有一个字符串。

6#666#665533999

我想把它拆分成多个小字符串(或者说直到字符变化为止),并且要忽略掉#,这样我就可以像手机拨号盘那样替换6 = M 或 666 = O 或 9 = W

6#666#665533999 -> 6, 666, 66, 55, 33, 999

所以我用了split('#')这个方法来去掉#,但接下来该怎么做我就搞不清楚了。我试过一些粗暴的方法,虽然能解决一部分问题,但有没有更简单或者更优雅的解决办法呢?

3 个回答

3

这段内容是关于编程问题的讨论,主要是在帮助那些遇到困难的人。它可能涉及到一些代码示例和解决方案,目的是让大家更好地理解如何解决特定的编程难题。

在这里,大家分享了他们的经验和技巧,可能还会提到一些常见的错误和如何避免它们。总之,这个讨论是为了让编程新手能够更轻松地掌握一些基本的概念和方法。

如果你有具体的代码或者问题,可以把它放在

def encode(nums):
    return ["".join(g) for k, g in itertools.groupby(nums) if k != '#']


chars = {str(n):dict(enumerate(chrs,1)) for n,chrs in enumerate("ABC DEF GHI JKL MNO PQRS TUV WXYZ".split(), 2)}

nums = "6#666#665533999"
nums = encode(nums)
message = ''.join(chars[n[0]][len(n)] for n in nums)

In [28]: message
Out[28]: 'MONKEY'
的地方,大家会一起帮你分析和解决。

4

这基本上是相同的逻辑,只是整理得更整齐了一些:

from itertools import groupby

phone_chars = {
    "2": " ABC",
    "3": " DEF",
    "4": " GHI",
    "5": " JKL",
    "6": " MNO",
    "7": " PQRS",
    "8": " TUV",
    "9": " WXYZ",
    "#": ["", ""]
}

def decode(digit_str):
    return "".join(phone_chars[ch][len(list(it))] for ch,it in groupby(digit_str))

然后

>>> print(decode("6#666#665533999"))
MONKEY

编辑:

Python有非常好的在线文档

itertools.groupby接受一个输入序列和一个可选的key参数,这个参数是一个评估函数——它接受一个值,进行某种处理,然后返回结果。如果没有提供key函数,它默认使用身份函数(也就是说key = lambda x: x,就是拿一个值返回同样的值)。

接着,它会把这个评估函数应用到输入序列中的每一个项目,并返回一个序列,内容是(评估后的值, iter(具有相同评估值的连续项目))

所以

groupby("AABBBCCCDD")

会得到

iter((
    ("A", iter(("A", "A"))),
    ("B", iter(("B", "B", "B"))),
    ("C", iter(("C", "C", "C"))),
    ("D", iter(("D", "D")))
))

或者(演示一个自定义的评估函数)

groupby([1, 2, 3, 4, 5, 6, 7], key=lambda x: x//3)

会得到

iter((
    (0, iter([1, 2])),      # 1//3 == 2//3 == 0
    (1, iter([3, 4, 5])),   # 3//3 == 4//3 == 5//3 == 1
    (2, iter([6, 7]))       # 6//3 == 7//3 == 2
))

注意,迭代器一次只给你一个值,而len对它是无效的,因为你无法知道迭代器可能返回多少个值。如果你需要计算返回的值,最简单的方法是len(list(iterable))——把所有返回的值放到一个列表里,然后看看这个列表有多少个项目。所以如果我们这样做

[(ch, len(list(it))) for ch,it in groupby("6#666#665533999")]

我们得到的结果是

[
    ('6', 1),   # => 'M'
    ('#', 1),   # => ''
    ('6', 3),   # => 'O'
    ('#', 1),   # => ''
    ('6', 2),   # => 'N'
    ('5', 2),   # => 'K'
    ('3', 2),   # => 'E'
    ('9', 3)    # => 'Y'
]

这(根据设计)正好是phone_chars中所需的索引值。我们用这些索引值来获取对应的字符——也就是说phone_chars['6'][1] == 'M'——然后用"".join()把它们连接起来,最后返回得到的字符串("MONKEY")。

11

使用 itertools.groupby

>>> c = "6#666#665533999"
>>> ["".join(g) for k, g in groupby(c) if k != '#']
['6', '666', '66', '55', '33', '999']

然后创建一个字典,把这些集合和拨号盘上的字符对应起来。

cmap = {'77': 'Q', '9999': 'Z'} # And so forth..

撰写回答