比方说,我有下面的元组列表

[('FRG', 'MCO TPA PIE SRQ', 'WAVEY EMJAY J174 SWL CEBEE '),
('                    ', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4'),
('                    ', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4')
('FRG2', 'MCO TPA PIE SRQ', 'WAVEY EMJAY J174 SWL CEBEE '),
('                    ', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4')]

我该如何将这些组合成一个单词,最后像这样:
{'FRG': ['MCO TPA PIE SRQ', 'WAVEY EMJAY J174 SWL CEBEE ', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4'],
 'FRG2': ...}

也就是说,我想将tuple[0]是一个单词的部分与tuple[0]是空的(只包含空白)后面的部分(可能很多)粘合在一起。
我从groupby开始尝试takewhileitertools,但没有得到任何工作溶液。理想情况下,解决方案包含其中一个(用于学习目的,即)。

最佳答案

函数groupbytakewhile不适合这种问题。
groupby
groupby基于akey函数的组。这意味着您需要保留最后遇到的第一个非空白元组元素才能使其工作。这意味着你要保持一些全球性的状态。通过保持这样的状态,函数被称为"unpure",而大多数(甚至所有)itertools是纯函数。

from itertools import groupby, chain

d = [('FRG',                  'MCO TPA PIE SRQ', 'WAVEY EMJAY J174 SWL CEBEE '),
     ('                    ', 'FMY RSW APF',     'WETRO DIW AR22 JORAY HILEY4'),
     ('                    ', 'FMY RSW APF',     'WETRO DIW AR22 JORAY HILEY4'),
     ('FRG2',                 'MCO TPA PIE SRQ', 'WAVEY EMJAY J174 SWL CEBEE '),
     ('                    ', 'FMY RSW APF',     'WETRO DIW AR22 JORAY HILEY4')]

def keyfunc(item):
    first = item[0]
    if first.strip():
        keyfunc.state = first
    return keyfunc.state

{k: [item for idx, item in enumerate(chain.from_iterable(grp)) if idx%3 != 0] for k, grp in groupby(d, keyfunc)}

takewhile
takewhile需要提前确定何时停止yielding值。这意味着它将从迭代器中自动弹出一个值,而不是实际用于每个组。要实际应用它,您需要记住最后一个位置,然后每次都创建一个新的迭代器。它还存在一个问题,即您需要保持某种状态,因为您希望先获取一个没有空格的元素,然后再获取那些只有空格的元素。
一种方法可能看起来像这样(但感觉不必要地复杂):
from itertools import takewhile, islice

def takegen(inp):
    idx = 0
    length = len(inp)
    while idx < length:
        first, *rest = inp[idx]
        rest = list(rest)
        for _, *lasts in takewhile(lambda x: not x[0].strip(), islice(inp, idx+1, None)):
            rest.extend(lasts)
        idx += len(rest) // 2
        yield first, rest

dict(takegen(d))

替代方案
你可以简单地创建你自己的生成器,使之变得非常简单。这是takewhile方法的一个变体,但它不需要外部状态,islicetakewhilegroupby或跟踪索引:
def gen(inp):
    # Initial values
    last = None
    for first, *rest in inp:
        if last is None:       # first encountered item
            last = first
            l = list(rest)
        elif first.strip():    # when the first tuple item isn't all whitespaces
            # Yield the last "group"
            yield last, l
            # New values for the next "group"
            last = first
            l = list(rest)
        else:                  # when the first tuple item is all whitespaces
            l.extend(rest)
    # Yield the last group
    yield last, l

dict(gen(d))
# {'FRG2': ['MCO TPA PIE SRQ', 'WAVEY EMJAY J174 SWL CEBEE ', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4'],
#  'FRG': ['MCO TPA PIE SRQ', 'WAVEY EMJAY J174 SWL CEBEE ', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4', 'FMY RSW APF', 'WETRO DIW AR22 JORAY HILEY4']}

关于python - Python IterTools分组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44640016/

10-12 19:54