Python では、いつリストを使用し、いつタプルを使用する必要がありますか?
選択の余地がない場合もあります。
"hello %s you are %s years old" % x
x はタプルでなければなりません。
しかし、私が API を設計し、データ型を選択できる場合、ガイドラインは何ですか?
タプルは本質的に固定サイズですが、リストは動的です。
つまり、 atuple
は不変ですが、 alist
は可変です。
in
演算子を使用して、要素がタプルに存在するかどうかを確認することもできます。タプルはリストよりも高速です。値の定数セットを定義していて、それを反復処理するだけの場合は、リストの代わりにタプルを使用してください。
変更する必要のないデータを「書き込み保護」すると、コードがより安全になります。リストの代わりにタプルを使用することは、このデータが定数であり、それをオーバーライドするには特別な考え方 (および特定の関数) が必要であるという暗黙の assert ステートメントを持つようなものです。
一部のタプルは辞書のキーとして使用できます (具体的には、文字列、数値、その他のタプルなどの不変値を含むタプル)。リストは不変ではないため、リストを辞書のキーとして使用することはできません。
出典: Python 3 に飛び込む
struct
C で s を使用するのと同様に、異種コレクション用のタプルと、配列を使用する場合と同様の同種コレクション用のリストという強い文化があります。しかし、これを他の回答で言及されている可変性の問題と完全に一致させたことはありません。可変性には歯があります (実際にはタプルを変更することはできません) が、均一性は強制されないため、それほど興味深い違いではないようです。
私は(そして私はPythonにほとんど精通していませんが)主な違いは、タプルが不変であり(割り当て後にその場で変更できない)、リストが可変である(追加、変更、減算などができる)ことだと信じています)。
そのため、私はタプルを割り当て後に変更してはならないものにし、リストを変更できるものにする傾向があります。
それは可変でなければなりませんか?リストを使用します。変更可能であってはなりませんか?タプルを使用します。
そうでなければ、それは選択の問題です。
異種オブジェクトのコレクション (名前、通り、都市、州、郵便番号に分割された住所など) には、タプルを使用することを好みます。それらはいつでも簡単に名前付きタプルに昇格できます。
同様に、コレクションを繰り返し処理する場合は、リストの方が好みです。複数のオブジェクトを 1 つにまとめて保持する単なるコンテナーである場合は、タプルを好みます。
最初に決定する必要があるのは、データ構造を可変にする必要があるかどうかです。すでに述べたように、リストは可変ですが、タプルはそうではありません。これは、タプルを辞書キーに使用できることも意味しますが、リストは使用できません。
私の経験では、タプルは通常、順序と位置が意味を持ち、一貫している場合に使用されます。たとえば、チョイス ユア オウン アドベンチャー ゲームのデータ構造を作成する際に、リストの代わりにタプルを使用することにしました。タプル内の位置に意味があるからです。そのデータ構造の一例を次に示します。
pages = {'foyer': {'text' : "some text",
'choices' : [('open the door', 'rainbow'),
('go left into the kitchen', 'bottomless pit'),
('stay put','foyer2')]},}
タプルの最初の位置は、ユーザーがゲームをプレイするときに表示される選択肢であり、2 番目の位置は選択肢が移動するページのキーであり、これはすべてのページで一貫しています。
タプルはリストよりもメモリ効率も優れていますが、その利点がいつ明らかになるかはわかりません。
Think Pythonのリストとタプルに関する章も参照してください。
しかし、私が API を設計し、データ型を選択できる場合、ガイドラインは何ですか?
入力パラメーターについては、必要なことを行う最も一般的なインターフェイスを受け入れるのが最善です。単なるタプルやリストであることはめったにありません - 多くの場合、シーケンス、スライス可能、または反復可能です。入力タイプを明示的にチェックしない限り、Python のダック タイピングは通常無料で取得できます。やむを得ない場合を除き、これを行わないでください。
生成するデータ (出力パラメーター) については、最も便利なものを返すだけです。たとえば、保持しているデータ型やヘルパー関数が返すものは何でも返します。
心に留めておくべきことの 1 つは、状態の一部であるリスト (またはその他の変更可能なもの) を返さないようにすることです。
class ThingsKeeper
def __init__(self):
self.__things = []
def things(self):
return self.__things #outside objects can now modify your state
def safer(self):
return self.__things[:] #it's copy-on-write, shouldn't hurt performance
タプルよりもリストの方が小さいながらも注目に値する利点は、リストの方が多少移植性が高いということです。標準ツールがタプルをサポートする可能性は低くなります。たとえば、JSON にはタプル型がありません。YAML はそうしますが、その構文はリスト構文に比べて醜く、非常に優れています。
そのような場合、タプルを内部で使用してから、エクスポート プロセスの一部としてリストに変換することをお勧めします。または、一貫性を保つために、あらゆる場所でリストを使用することもできます。