1

このコードのデバッグに何時間も費やしました。リストの最後から 2 番目の要素を取得したい。

for x, y in itertools.groupby(range(0,10), lambda x: int(x / 3)):
    print("the group's key is %d and values are %s" % (x, ','.join(map(str,y))))

temp = itertools.groupby(range(0,10), lambda x: int(x / 3))
the_last_one = None
second_to_last = None
for x,y in temp:
    second_to_last = the_last_one
    the_last_one = y
print(next(iter(second_to_last)))

デモンストレーション用の最初の部分の出力は次のとおりです。

the group's key is 0 and values are 0,1,2
the group's key is 1 and values are 3,4,5
the group's key is 2 and values are 6,7,8
the group's key is 3 and values are 9

2 番目の部分の目標は、最後から 2 番目のグループの最初の要素を出力することです。期待して6いますが、代わりに例外が発生しますStopIteration。最後の行を次のように変更すると:

print(next(the_last_one))

次に、期待される結果が得られ9ます。groupby作品の出力と同じ構造を持つタプルのリストを使用することもできます。このコードは反復子でのみ失敗します。

4

2 に答える 2

1

(何が起こっているかは知っていると思いますが、Python は初めてです。自由に編集してください!)

groupby はyieldのタプルを ing してい(int, iterator)ます。イテレータは を呼び出してrepeat()値を取得します。

私が呼び出して前にイテレータをnext()渡すと、それらの値はforeverの出力から消えました。 は次の出力で、second_to_last はイテレータの保存されていない過去を指すイテレータです。(この部分はよくわかりません…)[6,7,8]repeat() 9repeat()

反復子を second_to_last に保存するだけでは不十分です。値を保存する必要があります。解決策は、行を次のように変更することです。

the_last_one = list(y)

list()イテレータの結果を強制的にメモリに保存します。

于 2012-05-22T05:20:31.413 に答える
1

のドキュメントによるとitertools.groupby

返されるグループ自体は、基になる iterable を groupby() と共有するイテレータです。ソースが共有されているため、groupby() オブジェクトが進められると、前のグループは表示されなくなります。したがって、そのデータが後で必要になった場合は、リストとして保存する必要があります。

これは、最初に iterable を反復するときに iterable が消費されていることを意味します。

変化する

for x,y in temp:
    second_to_last = the_last_one
    the_last_one = y

for x,y in temp:
    second_to_last = the_last_one
    the_last_one = list(y)

値が繰り返されるときに値を保存します。

于 2012-05-22T05:54:44.613 に答える