给定一个整数,我需要创建一个元组列表,这样在每个元组中,第一个条目是数字的数字,第二个条目是频率的数字。这应该从数字的左边开始,数字的顺序很重要。例如11122311
将导致[('1', 3), ('2', 2),('3',1),('1',2)]
。
我不想使用像groupby
这样的内置函数。
我试图迭代一个字符串的元素,只要它们相同,然后剪切这些数字并再次迭代,直到字符串列表的长度为零。不幸的是,我不能成功地实施这一点。感谢您的帮助。谢谢
def compress(n):
L = []
while len(str(n)) != 0:
for i in range(len(str(n))):
for j in range(len(str(n))):
if str(n)[i] == str(n)[i+j]:
L.append((str(n)[i],j))
str(n) = str(n)[j:]
return L
print(compress(11122))
您可以通过保留前一个字符并保留一个"运行"-也就是说,在它改变之前你已经看到了多少个字符。
def compress_rle(s):
compressed = []
if not s:
return compressed
previous_character = s[0]
run = 0
for character in s:
if character != previous_character:
compressed.append((previous_character, run))
run = 0
run += 1
previous_character = character
compressed.append((previous_character, run))
return compressed
print(compress_rle('11122311'))
这与您在问题中给出的输出相同:
[('1', 3), ('2', 2), ('3', 1), ('1', 2)]
使用while
更好地处理迭代的一种方法:
def compress(n):
res = []
length, index = len(n), 0
while index < length:
last = n[index]
# while the current value is equal to the last iterate
run_length = 0
while index + run_length < length and n[index + run_length] == last:
run_length += 1
# append the run
res.append((last, run_length))
# move index forward
index += run_length
return res
print(compress("11122311"))
输出
[('1', 3), ('2', 2), ('3', 1), ('1', 2)]
使用元组跟踪运行次数的运行长度编码。
代码
def compress(n):
s, runs = str(n), []
for c in s:
if not runs or runs[-1][0] != c: # different letter->start new empty substring
runs.append((c, 0)) # new run count tuple
runs[-1] = (runs[-1][0], runs[-1][1] + 1) # increment run count
return runs
测试
print(compress(11122311)) # Out: [('1', 3), ('2', 2), ('3', 1), ('1', 2)]
您可以通过将输入转换为字符串,然后对每个数字进行计数来实现这一点。这可能是更清洁的方式
def compress(n):
n = str(n)
return [(n.count(c), c) for c in sorted(set(n))]
print(compress(11122))