这基本上是相同的逻辑,只是包装得更整齐一点:
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 有很好的online documentation。
itertools.groupby 接受一个输入序列和一个可选的key 参数,它是一个评估函数——它接受一个值,对它做一些事情,然后返回结果。如果没有给出key函数,则默认为identity(即key = lambda x: x,取一个值,返回相同的值)。
然后它将这个评估函数应用于输入序列中的每个项目,并返回一个(evaluated_value, iter(consecutive_items_having_the_same_evaluated_value))的序列。
所以
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")。