簡體   English   中英

如何使用itertools.groupby()獲取每個項目的索引和出現位置

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM