5

重複の可能性:
Pythonのローリングまたはスライディングウィンドウイテレータ

私はプログラミングに不慣れで、Pythonを学んでいます。私は問題を解決するための効率的/pythonicな方法を探しています。

組み合わせの要素が元の親イテラブルと同じ連続順序で表示される限り、親イテラブルの組み合わせを含むイテラブルのリストを返す関数が欲しいのですが。

この概念を「連続」と表現する正しい単語が通常「同じ要素が繰り返される」ことを意味する場合、「連続」であるかどうかはわかりません。例:[1,1,1]、'aaa'など..

つまり、リスト[1,2,3,4,5]が与えられた場合:

[1,2,3]は連続していますが、[1,2,4]は連続していません。(これについての言葉はありますか?)

これが私が作成した関数consecutive_combinations()と期待される動作です:

def consecutive_combinations(iterable, consec):
    begin = 0
    chunks = len(iterable) + 1 - consec
    return [iterable[x + begin: x + consec] for x in xrange(chunks)]

def test():
    t = (1,2,3,4,5)
    s = "The quick brown fox jumps over the lazy dog."
    CC = consecutive_combinations
    assert CC(t, 2) == [(1, 2), (2, 3), (3, 4), (4, 5)]
    assert CC(t, 3) == [(1, 2, 3), (2, 3, 4), (3, 4, 5)]
    assert CC(t, 4) == [(1, 2, 3, 4), (2, 3, 4, 5)]
    assert CC(t, 5) == [(1, 2, 3, 4, 5)]
    assert CC(s, 3) == ['The', 'he ', 'e q', ' qu', 'qui', 'uic', 'ick', 'ck ', 'k b', ' br', 'bro', 'row', 'own', 'wn ', 'n f', ' fo', 'fox', 'ox ', 'x j', '  ju', 'jum', 'ump', 'mps', 'ps ', 's o', ' ov', 'ove', 'ver', 'er ', 'r t', '    th', 'the', 'he ', 'e l', ' la', 'laz', 'azy', 'zy ', 'y d', ' do', 'dog', 'og. ']
    assert CC('', 3) == []
    print "All tests passed!"

test()

これは効率的な解決策ですか?itertoolsまたは他のビルド済みモジュールにこの種のことを行う何かがありますか?

4

2 に答える 2

7

私は実用的なzipアプローチが好きです:

n = 3
s = "The quick brown fox jumps over the lazy dog."
zip(*(s[i:] for i in xrange(n)))

これは非常に効率的ではなく、シーケンスに対してのみ機能しますが、多くの場合、十分に機能します。

対応するitertools解決策は、上記の非常に単純な変換です。

from itertools import izip, islice, tee

def slices(iterable, n):
    return izip(*(islice(it, i, None) for i, it in enumerate(tee(iterable, n))))

すっごくたくさんi...

それでも、これは反復可能なものでは機能するはずです(ただし、リストや文字列などの単純なシーケンスでは遅くなる可能性があります)。

于 2012-06-10T19:40:28.973 に答える
3

あなたの解決策は大丈夫です。ただし、少し短くすることもできます。例えば:

def subsequences(iterable, length):
    return [iterable[i: i + length] for i in xrange(len(iterable) - length + 1)]
于 2012-06-10T19:43:48.293 に答える