在准备考试的同时,我正在解决前几年的考试。
编写函数compress(lst)
,该函数接收一个非空的重复字母列表,并返回一个元组列表,每个元组都包含字母和数字或后续的重复。 (请参见示例)
例如:
针对:
['a','a', 'b', 'b', 'b', 'c', 'a', 'a']
该函数应返回:
[('a', 2), ('b', 3), ('c', 1), ('a', 2)]
这是我的代码:
def compress(lst):
res = []
i = 0
for letter in lst:
letter_count = 0
while i < len(lst) and lst[i] == letter:
letter_count += 1
i +=1
res.append((letter, letter_count))
return res
我的函数返回:
[('a', 2), ('a', 0), ('b', 3), ('b', 0), ('b', 0), ('c', 1), ('a', 2), ('a', 0)]
我知道为什么会这样做,但是我看不到如何更改我的代码来解决问题。
答案 0 :(得分:3)
使用itertools
模块中的groupby
,非常适合这里:
from itertools import groupby
lst = ['a','a', 'b', 'b', 'b', 'c', 'a', 'a']
print([(k, len(list(v))) for k, v in groupby(lst)])
# [('a', 2), ('b', 3), ('c', 1), ('a', 2)]
答案 1 :(得分:2)
(假设您要更正您的代码)
保存当前分析字母的index
,并求和该字母重复多少次,这样就跳过已分析的字母
def compress(lst):
res = []
i = 0
ind = 0
while ind < len(lst):
letter_count = 0
while i < len(lst) and lst[i] == lst[ind]:
letter_count += 1
i +=1
res.append((lst[ind], letter_count))
ind += letter_count
return res
>>> compress(['a','a', 'b', 'b', 'b', 'c', 'a', 'a'])
[('a', 2), ('b', 3), ('c', 1), ('a', 2)]
答案 2 :(得分:1)
问题在于while
循环正确地计算了发生次数,for
循环无情地前进,一次一个字符。由于您已经在while
循环中正确地增加了索引,所以最简单的方法是完全摆脱for
或while
循环。在这里进行多个循环的唯一目的是尝试避免使用if
,并且如您所见,这实际上是行不通的。
res = []
prev = ''
for letter in lst:
if prev == letter:
letter_count += 1
else:
if prev:
res.append((prev, letter_count))
letter_count = 1
prev = letter
这类似于您从itertools.groupby
获得的收益:
[(k, len(list(g))) for k, g in groupby(lst)]
答案 3 :(得分:1)
$ ls
file100.txt file10.txt file1.txt file2.txt file3.txt
$ rename -n 's/\d+/sprintf("%03d", $&)/e' *.txt
rename(file10.txt, file010.txt)
rename(file1.txt, file001.txt)
rename(file2.txt, file002.txt)
rename(file3.txt, file003.txt)
是Python方式。如果您想模拟它,则可以使用groupby
来实现,它只有一个循环,没有索引(不是很pythonic),并且有一个变量来存储前一个字母:
O(1)
结果:
def compress(lst):
res = []
previous_letter = None
count = 0
for letter in lst:
if previous_letter is None:
# first time
count += 1
previous_letter = letter
elif previous_letter == letter:
# same letter as before, count
count += 1
else:
# different letter: store result, reset counter
res.append((previous_letter,count))
count = 1
previous_letter = letter
# last iteration doesn't append the last result, fix this
res.append((previous_letter,count))
return res