range()
やZip()
などの関数をforループで使用する方法を理解しています。しかし、range()
がリストを出力することを期待していました-UNIXシェルのseq
によく似ています。次のコードを実行すると:
_a=range(10)
print(a)
_
出力はrange(10)
であり、リストではなく、異なるタイプのオブジェクトを示唆しています。 Zip()
は、印刷時に同様の動作をし、次のようなものを出力します
_<Zip object at "hexadecimal number">
_
だから私の質問は、それらが何であり、これを作ることにはどのような利点があるのか、そしてそれらをループすることなくリストに出力を得るにはどうすればよいですか?
Python 3。
Python 2)では、オブジェクトZip
およびrange
は、リストを返すように、提案どおりに動作しました。これらは generator に変更されましたリスト全体をメモリに展開するのではなく、要求に応じて要素を生成する-オブジェクトのようなもの。
「遅延」バージョンもPython 2.xにありますが、xrange
とitertools.izip
。
一度にすべての出力を使い慣れたリストオブジェクトに取得するには、単にlist
を呼び出して、コンテンツを繰り返し使用します。
>>> list(range(3))
[0, 1, 2]
>>> list(Zip(range(3), 'abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]
In Python 3.x.、 range
は、Python = 2.x.同様に、 Zip
はリストではなくZipオブジェクトを返すようになりました。
これらのオブジェクトをリストとして取得するには、それらを list
に配置します。
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> Zip('abc', 'abc')
<Zip object at 0x01DB7120>
>>> list(Zip('abc', 'abc'))
[('a', 'a'), ('b', 'b'), ('c', 'c')]
>>>
最初は役に立たないように思えるかもしれませんが、range
とZip
の動作のこの変更により、実際に効率が向上します。これは、Zipオブジェクトとrangeオブジェクトが、一度にすべてを保持するリストを作成するのではなく、必要に応じてアイテムを作成するためです。そうすることで、メモリ消費を節約し、操作速度を改善します。
範囲(xrange
in python 2. *)オブジェクトは 不変シーケンス で、Zip(itertools.izip
は、それぞれ) ジェネレーターオブジェクト です。ジェネレーターまたはシーケンスからリストを作成するには、単純にリストにキャストします。例えば:
>>> x = range(10)
>>> list(x)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ただし、要素の生成方法は異なります。通常のジェネレーターは可変であり、反復されるとその内容を検証しますが、範囲は不変であり、次のことは行いません。
>>> list(x) # x is a range-object
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # second cast to list, contents is the same
>>> y = Zip('abc', 'abc')
>>> list(y) # y is a generator
[('a', 'a'), ('b', 'b'), ('c', 'c')]
>>> list(y)
[] # second cast to list, content is empty!