Pythonでオブジェクトのリストを初期化する
-
05-07-2019 - |
質問
私は空ではないオブジェクトの配列/リストを初期化しようとしています-クラスコンストラクターはデータを生成します。 C ++とJavaでは、次のようにします。
Object lst = new Object[100];
掘り下げましたが、これを行うPythonの方法はありますか?
これは思ったようには機能しません(同じオブジェクトへの参照を100個取得します):
lst = [Object()]*100
しかし、これは私が望むように動作するようです:
lst = [Object() for i in range(100)]
リストの理解は(知的には)「たくさん」のように思えます。 Javaで非常に単純なもののための仕事の。
解決
C ++のように、配列の各要素に対して Object()
コンストラクタを暗黙的に呼び出す方法はありません(Javaでは、新しい配列の各要素は参照型の場合は null
)。
私はあなたのリスト内包法が最もPythonicであると言うでしょう:
lst = [Object() for i in range(100)]
レキシカル変数 i
を踏まない場合、Pythonの慣例では、値が重要でないダミー変数に _
を使用します。 :
lst = [Object() for _ in range(100)]
Javaの同様のコンストラクトに相当するものについては、もちろん *
を使用できます:
lst = [None] * 100
他のヒント
PythonはJavaコードと同等であることに注意してください (オブジェクトへの100個の null 参照の配列を作成):
Object arr = new Object[100];
またはC ++コード:
Object **arr = new Object*[100];
is:
arr = [None]*100
not:
arr = [Object() for _ in range(100)]
2番目はJavaのものと同じです:
Object arr = new Object[100];
for (int i = 0; i < arr.lenght; i++) {
arr[i] = new Object();
}
実際、複雑なデータ構造を初期化するPythonの機能は、Javaの機能よりもはるかに優れています。
注: C ++コード:
Object *arr = new Object[100];
Pythonのリストの理解と同じくらい多くの作業を行う必要があります:
-
100個のオブジェクトに連続メモリを割り当てる
-
このオブジェクトごとにObject :: Object()を呼び出す
そして、結果は完全に異なるデータ構造になります。
リストの内包表記は最も簡単な方法だと思いますが、それが気に入らなければ、明らかにそれがあなたが望むものを得る唯一の方法ではありません-引数なしで与えられたcallableを100回呼び出して100アイテムを形成します新しいリストの。たとえば、 itertools
は明らかにそれを行うことができます:
>>> import itertools as it
>>> lst = list(it.starmap(Object, it.repeat((), 100)))
または、あなたが本当に伝統主義者なら、 map
および apply
:
>>> lst = map(apply, 100*[Object], 100*[()])
これは本質的に同じであることに注意してください(概念的にも実際にも非常に少ないです;-)引数なしで呼び出す必要がある代わりに、 Object
を呼び出す必要がある場合にかかる作業量1つの引数-または、たとえば Object
が実際には型ではなく関数だった場合。
「リストの理解と同じくらい」かかるかもしれないという驚きからこのタスクを実行するには、すべての言語が「引数なしで型への呼び出し」を実行する必要性を特別に考慮すべきであると思われます。他の種類のover callablesへの呼び出しよりも、この非常に特殊なケースについて、他のすべてとは異なる扱いを保証するために、非常に重要で特別なことはわかりません。その結果、個人的には、Pythonがこの1つのケースを特異で奇妙な扱いのために選抜するのではなく、他の同様のユースケースと同じように定期的かつ簡単に処理できることを私はかなり喜んでいます!-)
lst = [Object() for i in range(100)]
配列はPythonの独自のファーストクラスオブジェクトなので、これが探しているものを取得する唯一の方法だと思います。 *クレイジーなことをします。