3

私は非常に初心者のプログラマーです。combinationsモジュールでツールを使用しようとしていitertoolsます。だから私は試します:

from itertools import *
print combinations('12345', 3)

('123', '124', '125', [...])しかし、予想されるのではなく、<itertools.combinations object at [pointer]>. 他のモジュールでメソッドを呼び出すと、次のような期待される結果が返されるため、非常に混乱しています。

import random
print random.randrange(10)
>>> 9

itertools モジュールのどこが間違っていますか?

4

4 に答える 4

6

Nothing. The result is what it should be. What you're apparently not accounting for is that the result is an iterator, not a fully evaluated list/tuple of results. The output you see is the repr() of that object (it's not returning a string). You can convert the former into the latter by passing it to the list constructor:

import itertools
print list(itertools.combinations('12345', 3))

But when you don't need that and you just iterate over the values, it saves a lot of memory by not storing all results at the same time. It also permits avoiding work by not consuming the whole iterator (for example, finding the first combination satisfying some condition and then returning).

于 2012-11-14T20:34:05.327 に答える
3

itertools.combinationsiterableを返します( Pythonドキュメントに記載されている同等のコードyieldでキーワードの使用を確認できます)。完全なシーケンスを印刷したい場合に使用できます。list(combinations(...))

>>> print list(combinations('12345', 3))
[('1', '2', '3'), ('1', '2', '4'), ('1', '2', '5'), ('1', '3', '4'), ('1', '3', '5' ('2', '3', '5'), ('2', '4', '5'), ('3', '4', '5')]
于 2012-11-14T20:32:28.747 に答える
2

それがイテレータです。orを使用してlistorに変換できます。tuplelist(combinations('12345', 3))tuple(combinations('12345', 3))

あなたの質問により、シーケンス、イテラブル、イテレータとは何かについて混乱していると思います。それらを完全に理解しておくと、Python コードを記述および/または理解できるようになると役立つと思いますので、この件について説明しようと思います。

およびオブジェクトはlistシーケンスです。シーケンスは、いくつかの特定の操作をサポートするオブジェクトです。つまり、それらはイテラブルであり(実行できます)、「アイテムアクセス」をサポートし(有効です)、「長さ」を持ち(有効です)、アイテムがシーケンス内にあるかどうかを確認できます(有効です)。[ 「シーケンスプロトコル」を構成する操作の完全なリストがあります。残念ながら、それはC-APIに固有のものです。それにもかかわらず、それらの関数の名前と説明は、それらがサポートする操作の完全なセットのアイデアを与えるはずです]tuplefor elem in sequencesequence[key]len(sequence)elem in sequence

Python には、場合によってはシーケンスの代わりに使用できる 2 種類のオブジェクトがあります: iterablesiteratorsです。

iterable は、反復をサポートするオブジェクトです。__iter__Python といえば、イテレータを返すメソッドがあれば、オブジェクトは反復可能です。

イテレータは、イテラブルを1 回反復し、値を 1 つずつ生成するオブジェクトです。Python では、反復子はメソッド ( python2 では)__iter__を実装するオブジェクトです。通常は「何もせず」、単にオブジェクト自体を返します。メソッドは iterable の次の値を返します。__next__next__iter__ next

現在、は iterable です。つまり、ループすることはできますが、構文をcombinations('12345', 3)使用してアイテムにアクセスすることはできず、 でその長さを取得することはできません。iterable[key]len

なぜイテレータを使用するのですか? 場合によっては、値のシーケンス全体をメモリに格納して反復処理することを回避できます。たとえば、数値をループしたい場合、数値1で満たされた長さの100を作成して反復処理する必要はありません。次の加算を計算できる値を与えます。list1001

したがって、基本的にイテラブルはメモリ使用量を削減する方法であり、一般に「何かをループする」ために必要な機能の抽象化です。シーケンスが必要な場合は、前述のように変換できます。

特別な種類の反復子は、いわゆるジェネレーターです。ジェネレーターは、関数構文を使用して記述できる単純な反復子であり、特に次のyieldキーワードを使用します。

>>> def numbers(n):
...     while n > 0:
...             yield n
...             n -= 1
... 
>>> numbers(5)
<generator object numbers at 0xb744a93c>
>>> for elem in numbers(5):
...     print elem
... 
5
4
3
2
1

ご覧のとおりnumbers、コードを呼び出すと実行されません。代わりに、python はイテレータであるジェネレータ オブジェクトを作成します。オブジェクトを反復処理すると、関数内のコードyieldが に遭遇するまで実行されます。これが発生すると、の「引数」yieldが返され、実行が凍結されます。新しい反復が開始されると、最初からやり直されます。

おそらく、次の例で実行の流れをよりよく確認できます。

>>> def flow():
...     yield 'Execution stopped here'
...     yield 'Execution continues'
...     yield 'Execution ended'
... 
>>> generator = flow()
>>> next(generator)   #same as generator.__next__()
'Execution stopped here'
>>> next(generator)
'Execution continues'
>>> next(generator)
'Execution ended'
>>> next(generator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

それらが提案されたPEP255を読むことに興味があるかもしれません。実際には、コルーチン機能を提供するように拡張されていますが、今のところはこれで十分だと思います。

于 2012-11-14T21:06:13.070 に答える
0

itertools.combinationクラスです。そのため、呼び出すとitertools.combinations()、そのクラスのインスタンスのインスタンスが返されます。これを反復して値を取得できます。

for combo in combinations('12345', 3):
    print combo
于 2012-11-14T20:33:21.547 に答える