[英]How to run-length encode without groupby
我已按如下顺序输入:
L = [5,5,7,7,7,7,9,10,12,14]
我想计算每个数字出现的次数。 这给出了输出:
[2,4,1,1,1,1]
我不需要存储原始值。 我也不想使用groupby。 这是因为我将使用pypy运行我的代码,从而最好地加快简单循环的速度。
我可以使用以下方法来低效地做到这一点:
S = set(L)
[L.count(item) for item in S]
是否有一个简单的线性时间解决方案,也许只是一个for循环?
如果您有非常大的数据,请编写一些功能以提高效率。
L1 = [1, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 9]
L2 = [1, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8]
def countr(lst):
res = []
count = 1
for i in range(len(lst) - 1):
if lst[i] == lst[i + 1]:
count += 1
else:
res.append(count)
count = 1
res.append(count)
return res
countr(L1)
# [4, 2, 1, 1, 1, 1, 1, 7, 1]
countr(L2)
# [4, 2, 1, 1, 1, 1, 1, 8]
这是Counter创建的目的:
>>> from collections import Counter
>>> counts = Counter([5,5,7,7,7,7,9,10,12,14])
>>> [counts[i] for i in sorted(counts.keys())]
[2, 4, 1, 1, 1, 1]
另外,如果您要优化内存使用量,则可以使用以下函数进行迭代,甚至是从文件获取数字的生成器:
def run_lengths(lst):
previous_val = None
num_vals = 0
for i in lst:
if previous_val is None:
previous_val = i
if i == previous_val:
num_vals += 1
continue
yield num_vals
previous_val = i
num_vals = 1
if num_vals:
yield num_vals
print(list(run_lengths([5,5,7,7,7,7,9,10,12,14]))) # Returns [1, 2, 4, 1, 1, 1]
def file_generator(file_path):
with open(file_path, 'r') as f:
for l in f:
yield int(l.strip())
print(list(run_lengths(file_generator('my/huge/file.dat'))))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.