違いは何ですか?
タプル/リストの利点/欠点は何ですか?
list
。; D
違いは何ですか?
タプル/リストの利点/欠点は何ですか?
list
。; D
回答:
タプルが不変であることとは別に、それらの使用をガイドする意味的な違いもあります。タプルは異種のデータ構造です(つまり、エントリの意味は異なります)が、リストは同種のシーケンスです。タプルには構造があり、リストには順序があります。
この区別を使用すると、コードがより明確で理解しやすくなります。
1つの例は、本の場所を参照するページと行番号のペアです。例:
my_location = (42, 11) # page number, line number
これを辞書のキーとして使用して、場所に関するメモを保存できます。一方、リストは複数の場所を格納するために使用できます。当然、リストに場所を追加または削除したい場合があるので、リストが変更可能であることは理にかなっています。一方、既存の場所にアイテムを追加したり削除したりすることは意味がありません。したがって、タプルは不変です。
たとえば、ページの行を反復するときなど、既存の場所タプル内のアイテムを変更したい場合があります。ただし、タプルの不変性により、新しい値ごとに新しい場所のタプルを作成する必要があります。これは一見不便に思われますが、このような不変データを使用することは、値型と関数型プログラミング手法の基礎であり、大きな利点があります。
この問題に関するいくつかの興味深い記事がありますが、例えば「Pythonのタプルは定数だけを一覧表示されない」または「Pythonでリストの対理解タプル」。公式のPythonドキュメントにもこれが記載されています
「タプルは不変であり、通常は異種のシーケンスを含んでいます...」。
Haskellのような静的に型付けされた言語のでは、タプルの値は一般に異なる型を持ち、タプルの長さを固定する必要があります。リストでは、値はすべて同じタイプで、長さは固定されていません。したがって、違いは非常に明白です。
最後に、Pythonにはnamedtupleがあります。これは、タプルがすでに構造を持つことになっているため、理にかなっています。これは、タプルはクラスやインスタンスの軽量な代替物であるという考えを強調しています。
collections.namedtuple
もっといい名前になっていると思いcollections.record
ます。たとえば、顧客レコードの名前と住所を入れ替えても意味がありません。実際、これを行うと通常はエラーとなり、タプルの不変性によりコミットできなくなります。
What would you do with such a list?
、私がpplがファンタジーの欠如を引数として使用するとき、私はいつも震えます。混合型リストの使用は、各リストが子リストと値要素で構成されるいくつかの階層データ構造などに適しています。
リストとタプルの違い
リテラル
someTuple = (1,2)
someList = [1,2]
サイズ
a = tuple(range(1000))
b = list(range(1000))
a.__sizeof__() # 8024
b.__sizeof__() # 9088
タプル操作のサイズが小さいため、少し速くなりますが、要素の数が非常に多くなるまでは、それほど言及する必要はありません。
許可された操作
b = [1,2]
b[0] = 3 # [3, 2]
a = (1,2)
a[0] = 3 # Error
つまり、要素を削除したり、タプルを並べ替えたりすることはできません。ただし、新しい要素をリストとタプルの両方に追加できますが、唯一の違いは、タプルは不変なので、要素を実際に追加するのではなく、新しいタプルを作成しているため、IDが変わるという点です。
a = (1,2)
b = [1,2]
id(a) # 140230916716520
id(b) # 748527696
a += (3,) # (1, 2, 3)
b += [3] # [1, 2, 3]
id(a) # 140230916878160
id(b) # 748527696
使用法
リストは変更可能であるため、辞書ではキーとして使用できませんが、タプルは使用できます。
a = (1,2)
b = [1,2]
c = {a: 1} # OK
c = {b: 1} # Error
3. Permitted operation
にタプルのケースを示しています。成功してからエラーを表示するのはよくあることですが、しばらくの間、頭が混乱しました。
one_item_list = [a]
ませんone_tuple = (a,)
が、対応するタプルです。変数名に続くコンマに注意してください。しかしまた注意してくださいtwo_tuple = (a, b)
。これにより、何度も私を追い出しました(まだPython 3に残っています)。
tuple(sorted(the_unsorted_tuple))
あなたが散歩に行った場合、あなたはいつでもあなたの座標を記録することができます (x,y)
タプル。
旅を記録したい場合は、数秒ごとに現在地をリストに追加できます。
しかし、逆にそれを行うことはできませんでした。
主な違いは、タプルは不変であることです。つまり、一度作成したタプルの値は変更できません。
したがって、値を変更する必要がある場合は、リストを使用してください。
タプルへの利点:
frozenset
またはさまざまなサードパーティのフリーズされたdict / treeなどのすべての不変コレクションにも当てはまると言えます。型ですが、どれも変更可能な要素を追加できません。(もちろん、タプルはすべての要素がハッシュ可能な場合にのみハッシュ可能です。これは通常のEAFPの方法で処理さd[1, [2]]
れるため、発生しTypeError: unhashable type: 'list'
ます。)
リストは変更可能です。タプルはそうではありません。
docs.python.org/2/tutorial/datastructures.htmlから
タプルは不変であり、通常、アンパック(このセクションの後半を参照)またはインデックス付け(または名前付きタプルの場合は属性によって)を介してアクセスされる要素の異種シーケンスを含みます。リストは変更可能であり、それらの要素は通常同種であり、リストを反復することによってアクセスされます。
だ言及されて違いが大きくセマンティックであること:人々はタプルとリストが異なる情報を表現することを期待しています。しかし、これはガイドラインよりもさらに進んでいます。一部のライブラリは、渡されたものに基づいて実際に異なる動作をします。NumPyを例にとります(他の例を求めている別の投稿からコピーしました)。
>>> import numpy as np
>>> a = np.arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> idx = (1,1)
>>> a[idx]
4
>>> idx = [1,1]
>>> a[idx]
array([[3, 4, 5],
[3, 4, 5]])
ポイントは、NumPyは標準ライブラリの一部ではないかもしれませんが、それは主要な Pythonライブラリであり、NumPyリストとタプル内では完全に異なるものです。
type(a_list) != type(a_tuple)
、そのため、に基づくライブラリコードの分岐のtype(x)
動作はそれぞれ異なります
'%d %d' % [2, 3]
はTypeError
です。最初のリストにリストを渡そうとし%d
ていて、2番目のリストには値を渡していないからです%d
。(ただし、これとは逆の例もありmax
ます。…)
リストはループ用、タプルは構造体用"%s %s" %tuple
です。
リストは通常同種で、タプルは通常異種です。
リストは可変長、タプルは固定長です。
これはPythonリストの例です:
my_list = [0,1,2,3,4]
top_rock_list = ["Bohemian Rhapsody","Kashmir","Sweet Emotion", "Fortunate Son"]
これはPythonタプルの例です:
my_tuple = (a,b,c,d,e)
celebrity_tuple = ("John", "Wayne", 90210, "Actor", "Male", "Dead")
Pythonのリストとタプルは、どちらも値の順序付けられたコレクションであるという点で似ています。括弧「[...、...]」を使用してリストが作成され、括弧「(...、...)」を使用してタプルが作成されるという浅い違いに加えて、それらの間のコア技術的な「Python構文でハードコードされた」違い特定のタプルの要素は不変ですが、リストは変更可能です(...タプルのみがハッシュ可能で、辞書/ハッシュキーとして使用できます!)。これにより、使用できる方法と使用できない方法の違い(構文によってアプリオリに強制される)と人々がそれらを使用することを選択する方法の違いが発生します(「ベストプラクティス」として後押しされ、これはスマートプログラマーが行うことです)。 人々は要素の順序を与えます。
タプルの場合、「順序」は情報を保持するための特定の「構造」にすぎません。最初のフィールドで見つかった値は2つ目のフィールドに簡単に切り替えることができます。それぞれが2つの異なるディメンションまたはスケールにわたって値を提供するためです。それらはさまざまなタイプの質問への回答を提供し、通常は次の形式になります。特定のオブジェクト/サブジェクトの場合、その属性は何ですか?オブジェクト/サブジェクトは一定のままで、属性は異なります。
リストの場合、「順序」はシーケンスまたは方向性を意味します。2番目の要素は後に来る必要があります、特定の一般的なスケールまたは寸法に基づいて2番目に配置されるため、最初の要素のに必要があります。要素は全体として解釈され、通常、フォームの単一の質問に対する回答を提供します。特定の属性について、これらのオブジェクト/サブジェクトはどのように比較されますか?属性は一定のままで、オブジェクト/サブジェクトは異なります。
ポピュラーカルチャーの人々やプログラマーがこれらの違いを理解しない例は無数にあり、メインコースにサラダフォークを使用する可能性のある無数の人々がいます。結局のところ、それは大丈夫であり、通常はどちらも仕事を成し遂げることができます。
より細かい詳細のいくつかを要約するには
類似点:
インデックス付け、選択、スライス -タプルとリストの両方が、括弧内にある整数値を使用してインデックスを作成します。したがって、特定のリストまたはタプルの最初の3つの値が必要な場合、構文は同じになります。
>>> my_list[0:3]
[0,1,2]
>>> my_tuple[0:3]
[a,b,c]
比較と並べ替え -2つのタプルまたは2つのリストは両方とも最初の要素によって比較されます。同数の場合は2番目の要素というように比較されます。以前の要素が違いを示した後は、後続の要素にはこれ以上注意を払いません。
>>> [0,2,0,0,0,0]>[0,0,0,0,0,500]
True
>>> (0,2,0,0,0,0)>(0,0,0,0,0,500)
True
違い: -アプリオリ、定義により
構文 -リストは[]を使用し、タプルは()を使用します
可変性 -指定されたリスト内の要素は変更可能であり、指定されたタプル内の要素は変更可能ではありません。
# Lists are mutable:
>>> top_rock_list
['Bohemian Rhapsody', 'Kashmir', 'Sweet Emotion', 'Fortunate Son']
>>> top_rock_list[1]
'Kashmir'
>>> top_rock_list[1] = "Stairway to Heaven"
>>> top_rock_list
['Bohemian Rhapsody', 'Stairway to Heaven', 'Sweet Emotion', 'Fortunate Son']
# Tuples are NOT mutable:
>>> celebrity_tuple
('John', 'Wayne', 90210, 'Actor', 'Male', 'Dead')
>>> celebrity_tuple[5]
'Dead'
>>> celebrity_tuple[5]="Alive"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
ハッシュテーブル(ディクショナリ) -ハッシュテーブル(ディクショナリ)では、そのキーがハッシュ可能で不変である必要があるため、リストではなく、タプルのみがディクショナリキーとして機能できます。
#Lists CAN'T act as keys for hashtables(dictionaries)
>>> my_dict = {[a,b,c]:"some value"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
#Tuples CAN act as keys for hashtables(dictionaries)
>>> my_dict = {("John","Wayne"): 90210}
>>> my_dict
{('John', 'Wayne'): 90210}
違い-使用中の事後
要素の同種性と異種性-通常、リストオブジェクトは同種で、タプルオブジェクトは異種です。つまり、リストは同じタイプのオブジェクト/サブジェクト(すべての大統領候補、またはすべての歌、またはすべてのランナーなど)に使用されますが、強制されていませんが)、タプルは異種オブジェクトに適しています。
ループと構造-どちらもループが可能(my_listのxの場合)... タプルは情報の構造化と表示により適しています(%sにある%s%sは%sであり、現在%s%( "John"、 "Wayne"、90210、 "Actor"、 "Dead"))
タプルとリストは、Pythonではどちらも一見似たシーケンス型です。
リテラル構文
括弧()を使用してタプルと角括弧
[ ]
を作成し、新しいリストを取得します。また、適切なタイプの呼び出しを使用して、必要な構造(タプルまたはリスト)を取得できます。
someTuple = (4,6)
someList = [2,6]
変異性
タプルは不変ですが、リストは変更可能です。この点が以下の基本となります。
メモリ使用量
可変性のため、リストにはより多くのメモリが必要で、タプルにはより少ないメモリが必要です。
拡張する
タプルとリストの両方に新しい要素を追加できますが、タプルのIDが変更される点のみが異なります(つまり、新しいオブジェクトが作成されます)。
ハッシュ
タプルはハッシュ可能で、リストはハッシュ可能ではありません。これは、タプルを辞書のキーとして使用できることを意味します。リストは辞書のキーとして使用できませんが、タプルは使用できます
tup = (1,2)
list_ = [1,2]
c = {tup : 1} # ok
c = {list_ : 1} # error
意味論
このポイントは、ベストプラクティスの詳細です。リストは同種のシーケンスですが、タプルは異種のデータ構造として使用する必要があります。
リストは同種のシーケンスであることが意図されていますが、タプルは異種のデータ構造です。
人々はここですでにtuples
不変である一方lists
でミュータブルであると答えましたが、タプルの使用には覚えておくべき重要な側面が1つあります
場合はtuple
含まれていlist
たりdictionary
、その中に、それらがあっても変更することができtuple
、それ自体は不変です。
たとえば、次のようなリストと辞書を含むタプルがあるとします。
my_tuple = (10,20,30,[40,50],{ 'a' : 10})
リストの内容を次のように変更できます
my_tuple[3][0] = 400
my_tuple[3][1] = 500
新しいタプルは次のようになります
(10, 20, 30, [400, 500], {'a': 10})
タプル内の辞書を次のように変更することもできます
my_tuple[4]['a'] = 500
全体のタプルは次のようになります
(10, 20, 30, [400, 500], {'a': 500})
これは、list
およびdictionary
オブジェクトであり、これらのオブジェクトは変更されていないために発生します。
だからtuple
例外なく不変のまま
PEP 484 -タイプヒントの要素の型があること言うtuple
個別に入力することもできます。あなたが言うことができるようにTuple[str, int, float]
; しかし、型付きクラスはlist
、List
型パラメーターを1つしか取ることができません。List[str]
、2の違いは本当に、前者が後者は本質的に均質で、異質であるということであることをどのヒント。
また、標準ライブラリは主に、Cがを返すような標準関数からの戻り値としてタプルを使用しstruct
ます。
人々はすでに違いを述べたので、タプルを選ぶ理由について書きます。
タプルが望ましいのはなぜですか?
小さなタプルの割り当て最適化
メモリの断片化を減らし、割り当てを高速化するために、Pythonは古いタプルを再利用します。タプルが不要になり、アイテムが20個未満の場合、タプルを完全に削除するのではなく、Pythonはフリーリストに移動します。
フリーリストは20のグループに分割され、各グループは0〜20の長さnのタプルのリストを表します。各グループは最大2000のタプルを格納できます。最初の(ゼロ)グループには要素が1つだけ含まれ、空のタプルを表します。
>>> a = (1,2,3)
>>> id(a)
4427578104
>>> del a
>>> b = (1,2,4)
>>> id(b)
4427578104
上記の例では、aとbのIDが同じであることがわかります。これは、フリーリストにある破壊されたタプルをすぐに占有したためです。
リストの割り当て最適化
リストは変更できるため、Pythonはタプルと同じ最適化を使用しません。ただし、Pythonリストにも空きリストがありますが、空のオブジェクトに対してのみ使用されます。空のリストがGCによって削除または収集された場合、後で再利用できます。
>>> a = []
>>> id(a)
4465566792
>>> del a
>>> b = []
>>> id(b)
4465566792
ソース: https //rushter.com/blog/python-lists-and-tuples/
タプルがリストよりも効率的である理由 -> https://stackoverflow.com/a/22140115
タプルはリストに似ているように見えるかもしれませんが、多くの場合、さまざまな状況でさまざまな目的で使用されます。タプルは不変であり、通常、アンパック(このセクションの後半を参照)またはインデックス付け(または名前付きタプルの場合は属性によって)を介してアクセスされる要素の異種シーケンスを含みます。リストは可変であり、それらの要素は通常同種であり、リストを反復することによってアクセスされます。
まず、どちらもPythonでは非スカラーオブジェクト(複合オブジェクトとも呼ばれます)です。
+
(もちろん、新しいタプルが作成されます)(3,) # -> (3)
代わりにシングルトン(3) # -> 3
[3]
new_array = origin_array[:]
[x**2 for x in range(1,7)]
はあなたに与える
[1,4,9,16,25,36]
(読めない)リストを使用すると、エイリアスのバグ(同じオブジェクトを指す2つの異なるパス)が発生する場合もあります。
リストは変更可能で、タプルは不変です。この例を考えてみてください。
a = ["1", "2", "ra", "sa"] #list
b = ("1", "2", "ra", "sa") #tuple
リストとタプルのインデックス値を変更します。
a[2] = 1000
print a #output : ['1', '2', 1000, 'sa']
b[2] = 1000
print b #output : TypeError: 'tuple' object does not support item assignment.
したがって、許可されていないタプルを更新しようとしたため、次のコードがタプルに対して無効であることを証明しました。
リストは変更可能で、タプルは不変です。可変と不変の主な違いは、アイテムを追加しようとするときのメモリ使用量です。
変数を作成すると、固定メモリが変数に割り当てられます。リストの場合、実際に使用されるよりも多くのメモリが割り当てられます。たとえば、現在のメモリ割り当てが100バイトの場合、101番目のバイトを追加するときに、別の100バイトが割り当てられる可能性があります(この場合、合計で200バイト)。
ただし、新しい要素を頻繁に追加しないことがわかっている場合は、タプルを使用する必要があります。タプルは必要なメモリのサイズを正確に割り当てるため、特にメモリの大きなブロックを使用する場合はメモリを節約できます。