[英]How to get the index and occurance of each item using itertools.groupby()
这是我有两个清单的故事:
list_one=[1,2,9,9,9,3,4,9,9,9,9,2]
list_two=["A","B","C","D","A","E","F","G","H","Word1","Word2"]
我想在list_one中找到连续的9的索引,以便可以从list_two获取相应的字符串,我已经尝试过:
group_list_one= [(k, sum(1 for i in g),pdn.index(k)) for k,g in groupby(list_one)]
我希望获得每个元组中前9个的索引,然后尝试从那里开始,但是那没有用。
我在这里可以做什么? PS:我看过itertools的文档,但对我来说似乎很模糊。
编辑:预期的输出是(键,次数,index_of_first_occurance)像
[(9, 3, 2), (9, 4, 7)]
从您的预期输出来看,尝试一下:
from itertools import groupby
list_one=[1,2,9,9,9,3,4,9,9,9,9,2]
list_two=["A","B","C","D","A","E","F","G","H","Word1","Word2"]
data = zip(list_one, list_two)
i = 0
out = []
for key, group in groupby(data, lambda x: x[0]):
number, word = next(group)
elems = len(list(group)) + 1
if number == 9 and elems > 1:
out.append((key, elems, i))
i += elems
print out
输出:
[(9, 3, 2), (9, 4, 7)]
但是,如果您真的想要这样的输出:
[(9, 3, 'C'), (9, 4, 'G')]
然后看一下这段代码:
from itertools import groupby
list_one=[1,2,9,9,9,3,4,9,9,9,9,2]
list_two=["A","B","C","D","A","E","F","G","H","Word1","Word2"]
data = zip(list_one, list_two)
out = []
for key, group in groupby(data, lambda x: x[0]):
number, word = next(group)
elems = len(list(group)) + 1
if number == 9 and elems > 1:
out.append((key, elems, word))
print out
好的,我有oneliner解决方案。 这很丑,但请忍受我。
让我们考虑这个问题。 我们有一个列表要使用itertools.groupby进行汇总。 groupby为我们提供了键列表及其重复的迭代。 在此阶段,我们无法计算索引,但可以轻松找到发生次数。
[(key, len(list(it))) for (key, it) in itertools.groupby(list_one)]
现在,真正的问题是我们要计算与旧数据相关的索引。 在大多数单行通用功能中,我们仅检查当前状态。 但是,有一个功能让我们瞥一眼过去reduce
。
reduce
作用是遍历迭代器并执行具有该函数和新项的最后结果的函数。 例如, reduce(lambda x,y: x*y, [2,3,4])
将计算2 * 3 = 6,然后6 * 4 = 24并返回24。此外,您可以为x选择另一个首字母而不是第一项。
让我们在这里使用它-对于每个项目,索引将是最后一个索引+最后出现的次数。 为了获得有效的列表,我们将使用[(0,0,0)]作为初始值。 (我们最终摆脱了它)。
reduce(lambda lst,item: lst + [(item[0], item[1], lst[-1][1] + lst[-1][-1])],
[(key, len(list(it))) for (key, it) in itertools.groupby(list_one)],
[(0,0,0)])[1:]
如果我们不添加初始值,则可以将到目前为止出现的次数相加。
reduce(lambda lst,item: lst + [(item[0], item[1], sum(map(lambda i: i[1], lst)))],
[(key, len(list(it))) for (key, it) in itertools.groupby(list_one)], [])
当然,它给了我们所有的数字。 如果只需要9,则可以将整个内容包装在filter
:
filter(lambda item: item[0] == 9, ... )
好吧,这可能不是最优雅的解决方案,但是这里有:
g = groupby(enumerate(list_one), lambda x:x[1])
l = [(x[0], list(x[1])) for x in g if x[0] == 9]
[(x[0], len(x[1]), x[1][0][0]) for x in l]
这使
[(9, 3, 2), (9, 4, 7)]
这看起来像一个问题,太复杂了,无法坚持到列表理解中。
element_index = 0 #the index in list_one of the first element in a group
for element, occurrences in itertools.groupby(list_one):
count = sum(1 for i in occurrences)
yield (element, count, element_index)
element_index += count
如果您想消除element_index
变量,请考虑一个cumulative_sum函数需要做什么,它的值取决于所有已迭代的先前值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.