1

検証に使用するライブラリ/ユーティリティを作成しています。一連の要素と、それらを何らかの順序で使用するテスト対象システムを用意します。セットは可能なすべての入力を表し、システムはそれらの要素の有限シーケンスを受け取ります。

有限シーケンスのセットは無限になるため、セットのすべてのシーケンスを計算するつもりはありませんが、代わりに Python ジェネレーターを使用して次のことを達成することを想定しています。

def seq(s): # s is a set
  length = 0
  nth = 0
  # r = calculate nth sequence of length
  # if there are no more sequences of length, length += 1
  # else n += 1, yield r

最終的にはこれを単射および全単射シーケンスに拡張しますが、現時点では集合の要素は何度でも出現できます。

ジェネレーターはこれにアプローチする最良の方法ですか? このようなジェネレーターを使用すると、再帰から得られる単純さがなくなりますか? 誰かが私を助けるかもしれない itertools (または他のモジュール) ショートカットに私を向けることができますか?

4

1 に答える 1

2

を探しているようですitertools.product。私はこれがあなたが求めていることをすると信じています:

def seq(s):
    length = 1
    while True:
        for p in itertools.product(s, repeat=length):
            yield p
        length += 1

これで、次のようなことができます。

>>> zip(range(10), seq(set((1, 2, 3))))
[(0, (1,)), (1, (2,)), (2, (3,)), (3, (1, 1)), (4, (1, 2)), 
 (5, (1, 3)), (6, (2, 1)), (7, (2, 2)), (8, (2, 3)), (9, (3, 1))]

またはこれ:

>>> test_seq = itertools.izip(itertools.count(), seq(set((1, 2, 3))))
>>> for i in range(10):
...     next(test_seq)
... 
(0, (1,))
(1, (2,))
(2, (3,))
(3, (1, 1))
(4, (1, 2))
(5, (1, 3))
(6, (2, 1))
(7, (2, 2))
(8, (2, 3))
(9, (3, 1))

これは、 other を使用してさらに圧縮することもできますitertools

>>> from itertools import chain, product, count
>>> s = set((1, 2, 3))
>>> test_seq = chain.from_iterable(product(s, repeat=n) for n in count(1))
>>> zip(range(10), test_seq)
[(0, (1,)), (1, (2,)), (2, (3,)), (3, (1, 1)), (4, (1, 2)), (5, (1, 3)), 
 (6, (2, 1)), (7, (2, 2)), (8, (2, 3)), (9, (3, 1))]
于 2012-04-19T13:25:11.243 に答える