11

スライディングペアでリストを反復処理する最もPythonの効率的な方法は何ですか? 関連する例を次に示します。

>>> l
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> for x, y in itertools.izip(l, l[1::2]): print x, y
... 
a b
b d
c f

これはペアでの反復ですが、スライディング ペアを反復するにはどうすればよいでしょうか? ペアの反復の意味:

a b
b c
c d
d e
etc.

これは、ペアを 2 要素ではなく 1 要素ずつスライドさせることを除いて、ペアの反復です。ありがとう。

4

7 に答える 7

15

あなたはさらに簡単に行くことができます。リストとリストを1つオフセットして圧縮するだけです。

In [4]: zip(l, l[1:])
Out[4]: [('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('e', 'f'), ('f', 'g')]
于 2012-10-22T15:28:04.857 に答える
9

どうですか:

for x, y in itertools.izip(l, l[1:]): print x, y
于 2012-10-22T15:27:35.747 に答える
4

これは、同様のシナリオのためにしばらく前に書いた小さなジェネレーターです。

def pairs(items):
    items_iter = iter(items)
    prev = next(items_iter)

    for item in items_iter:
        yield prev, item
        prev = item
于 2012-10-22T15:27:02.153 に答える
4

これは、リストだけでなくイテレーター/ジェネレーターでも機能する、任意のサイズのスライディング ウィンドウの関数です。

def sliding(seq, n):
  return izip(*starmap(islice, izip(tee(seq, n), count(0), repeat(None))))

ただし、ネイサンのソリューションはおそらくより効率的です。

于 2012-10-22T15:41:40.087 に答える
1

リスト内の 2 つの後続のエントリの追加によって定義されるタイミングは、下に表示され、最も速いものから最も遅いものの順序で表示されます。

ギル

In [69]: timeit.repeat("for x,y in itertools.izip(l, l[1::1]): x + y", setup=setup, number=1000)
Out[69]: [1.029047966003418, 0.996290922164917, 0.998831033706665]

ジェフ・リーディ

In [70]: timeit.repeat("for x,y in sliding(l,2): x+y", setup=setup, number=1000)
Out[70]: [1.2408790588378906, 1.2099130153656006, 1.207326889038086]

アレスタニス

In [66]: timeit.repeat("for i in range(0, len(l)-1): l[i] + l[i+1]", setup=setup, number=1000)
Out[66]: [1.3387370109558105, 1.3243639469146729, 1.3245630264282227]

チムリグ

In [68]: timeit.repeat("for x,y in zip(l, l[1:]): x+y", setup=setup, number=1000)
Out[68]: [1.4756009578704834, 1.4369518756866455, 1.5067830085754395]

ネイサン・ヴィレスクサ

In [63]: timeit.repeat("for x,y in pairs(l): x+y", setup=setup, number=1000)
Out[63]: [2.254757881164551, 2.3750967979431152, 2.302199125289917]

sr2222

繰り返し回数が減っていることに注意してください...

In [60]: timeit.repeat("for x,y in SubsequenceIter(l,2): x+y", setup=setup, number=100)
Out[60]: [1.599524974822998, 1.5634570121765137, 1.608154058456421]

セットアップ コード:

setup="""
from itertools import izip, starmap, islice, tee, count, repeat
l = range(10000)

def sliding(seq, n):
  return izip(*starmap(islice, izip(tee(seq, n), count(0), repeat(None))))

class SubsequenceIter(object):

    def __init__(self, iterable, subsequence_length):

        self.iterator = iter(iterable)
        self.subsequence_length = subsequence_length
        self.subsequence = [0]

    def __iter__(self):

        return self

    def next(self):

        self.subsequence.pop(0)
        while len(self.subsequence) < self.subsequence_length:
            self.subsequence.append(self.iterator.next())
        return self.subsequence

def pairs(items):
    items_iter = iter(items)
    prev = items_iter.next()

    for item in items_iter:
        yield (prev, item)
        prev = item
"""
于 2012-10-22T16:12:40.737 に答える
0

最も効率的というわけではありませんが、非常に柔軟です。

class SubsequenceIter(object):

    def __init__(self, iterable, subsequence_length):

        self.iterator = iter(iterable)
        self.subsequence_length = subsequence_length
        self.subsequence = [0]

    def __iter__(self):

        return self

    def next(self):

        self.subsequence.pop(0)
        while len(self.subsequence) < self.subsequence_length:
            self.subsequence.append(self.iterator.next())
        return self.subsequence

使用法:

for x, y in SubsequenceIter(l, 2):
    print x, y
于 2012-10-22T15:40:52.633 に答える