3

たとえば、リストが与えられた場合、他のすべての要素x = [True]*20に割り当てたいと思います。False

x[::2] = False

上げるTypeError: must assign iterable to extended slice

だから私はあなたがこのようなことをすることができると素朴に仮定しました:

x[::2] = itertools.repeat(False)

また

x[::2] = itertools.cycle([False])

しかし、私が知る限り、これは無限ループになります。なぜ無限ループがあるのですか?割り当て前にスライス内の要素の数を知ることを含まない代替アプローチはありますか?

編集:私はそれx[::2] = [False] * len(x)/2がこの場合に機能することを理解しています、またはあなたはより一般的な場合の右側の乗数の式を思い付くことができます。itertoolsが無期限に循環する原因と、リストの割り当てがnumpy配列の割り当てとは異なる動作をする理由を理解しようとしています。私が誤解しているPythonには何か基本的なことがあるに違いないと思います。また、もともと、リスト内包表記や別のn要素リストの作成よりもitertoolsを好むパフォーマンス上の理由があるのではないかと考えていました。

4

5 に答える 5

3

このコードであなたがやろうとしていることは、あなたが考えていることではありません(私は疑っています)。たとえば、 x の
x[::2]すべての要素を含むスライスを返し ます.サイズ1の非イテラブルをそれに割り当てます。odd

持っているコードを正常に使用するには、次のことを行う必要があります。

x = [True]*20
x[::2] = [False]*10

サイズ10のイテラブルをサイズ10のスライスに割り当てます。

要素の数を考慮して暗闇で作業するのはなぜですか? 使用する

len(x[::2])  

これは 10 に等しく、次に使用します。

x[::2] = [False]*len(x[::2])

次のようなこともできます。

x = [True if (index & 0x1 == 0) else False for index, element in enumerate(x)]

編集:OP編集のため

サイクルに関するドキュメントには、指定されたイテレータを継続的に「循環」することを意味Repeats indefinitely.すると書かれています。

Repeat にも同様の実装がありますが、ドキュメント
Runs indefinitely unless the times argument is specified.
には質問コードで行われていないことが記載されています。したがって、どちらも無限ループにつながります。

itertoolsより速いコメントについて。はい、 itertools は一般的に他の実装よりも高速です。これは、作成者ができる限り高速になるように最適化されているためです。

ただし、リストを再作成したくない場合はgenerator expressions、次のように使用できます。

x = (True if (index & 0x1 == 0) else False for index, element in enumerate(x))

すべての要素をメモリに保存するのではなく、必要に応じて生成しますが、ジェネレーター関数を使い果たす可能性があります。

例えば:

x = [True]*20
print(x)
y = (True if (index & 0x1 == 0) else False for index, element in enumerate(x))
print ([a for a in y])
print ([a for a in y])

xジェネレーターが使い果たされているため、ジェネレーター内の要素y、次に null リストを出力します。

于 2011-12-01T04:35:55.240 に答える
2

Mark Tolonen が簡潔なコメントで指摘したように、あなたの itertools の試行が無期限に繰り返される理由は、リストの割り当てのために、python が右側の長さをチェックしているためです。

では、本格的に掘り下げていきます...

あなたが言う時:

x[::2] = itertools.repeat(False)

左側 ( ) はリストであり、値がiterable でx[::2]あるリストに値を割り当てています。これは、長さが指定されていないため、永遠に反復されます ( docsに従って)。itertools.repeat(False)

cPython 実装のリスト割り当てコードを掘り下げると、残念ながら/痛々しい名前の function が見つかります。list_ass_sliceこれは、多くのリスト割り当てのルートにあります。そのコードには、次のセグメントが表示されます。

v_as_SF = PySequence_Fast(v, "can only assign an iterable");
if(v_as_SF == NULL)
    goto Error;
n = PySequence_Fast_GET_SIZE(v_as_SF);

ここではn、リストに割り当てている iterable の長さ ( ) を取得しようとしています。ただし、そこにたどり着く前に に行き詰まりPySequence_FastPySequence_List最終的には空のリストを作成し、反復可能オブジェクトで単純に拡張しようとします。

iterable を使用してリストを拡張するにはlistextend()、 を使用します。そこに問題の根本が表示されます。

/* Run iterator to exhaustion. */
for (;;) {

そして、そこに行きます。

または、少なくともそう思います... :) 興味深い質問だったので、ソースを掘り下げて何が起きているのかを調べて、そこにたどり着いたと思いました。

numpy 配列での動作の違いに関しては、numpy.array割り当ての処理方法が異なるだけです。

itertools.repeatusingはnumpyでは機能しませんが、ハングアップしないことに注意してください(理由を理解するために実装をチェックしませんでした):

>>> import numpy, itertools
>>> x = numpy.ones(10,dtype='bool')
>>> x[::2] = itertools.repeat(False)
>>> x
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)
>>> #but the scalar assignment does work as advertised...
>>> x = numpy.ones(10,dtype='bool')
>>> x[::2] = False
>>> x
array([False,  True, False,  True, False,  True, False,  True, False,  True], dtype=bool)
于 2011-12-01T07:46:35.897 に答える
1

これを試して:

l = len(x)
x[::2] = itertools.repeat(False, l/2 if l % 2 == 0 else (l/2)+1)

ドキュメントrepeatから、それが本来の目的であるため、元のソリューションは無限ループに陥ります。

オブジェクトを何度も返すイテレータを作成します。times 引数が指定されない限り、無期限に実行されます。

于 2011-12-01T04:37:36.243 に答える
0

スライスx[::2]は正確にlen(x)/2要素の長さであるため、次の方法で目的を達成できます。

x[::2] = [False]*(len(x)/2)

itertools.repeatおよびメソッドは、itertools.cycle値を無限に生成するように設計されています。ただし、に制限を指定できますrepeat()。このような:

x[::2] = itertools.repeat(False, len(x)/2)
于 2011-12-01T04:42:47.523 に答える
0

拡張スライス割り当ての右側は、適切なサイズ (この場合は 10) の iterable である必要があります。

これは、右側に通常のリストがあります。

>>> x = [True] * 20
>>> x[::2] = [False] * 10
>>> x
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]

そして、これは右側のitertools.repeatにあります。

>>> from itertools import repeat
>>> x = [True] * 20
>>> x[::2] = repeat(False, 10)
>>> x
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]
于 2011-12-01T05:40:31.923 に答える