質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Python

    8041questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

tupleとlistの違い

解決済

回答 4

投稿

  • 評価
  • クリップ 2
  • VIEW 592

gontaros0302

score 6

tupleとlistの違いとして、
① tupleは変更不可だから緯度のような不変のものに使える
② listよりもパフォーマンスが良い(実行速度が少し早い)
とwebに書いていました。

しかし、別のtupleを作って連結することで要素の追加のような振る舞いができる。ともあったのですが

要は、

tuple_player = (‘honda’, ‘kagawa’, ‘Hasebe
‘)


のようなtupleがあった時に、そのものが変更できないという理解で正しいのでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+7

LouiS0616さんの回答されている点をまず理解するのが基本と思います。その上で

別のtupleを作って連結することで要素の追加のような振る舞いができる。ともあったのですが

正確にいえば「一度生成したtupleは要素を違う値に置き換えたり、別のtupleを直接連結できない」です。「別のtupleを作って連結する」の正確な意味は「一旦作ったtuple(A)に別のtuple(B)をくっつけたかのような新たなtuple(C)を作り出すことができる」ということです。

a = (1, 2)
b = a
a += (3,)
print(a)    # (1, 2, 3)
print(b)    # (1, 2)

つまり
a += (3,)
は以下のように書いたのと同じ動作になり
a = a + (3,)
右辺を計算すると新たなtupleが作られ、それを変数aへ代入しているだけなのです。
aにあった元のtupleの値が変化するわけではありません。

一方listは違います。

a = [1, 2]
b = a
a += [3]
print(a)   # [1, 2, 3]
print(b)   # [1, 2, 3]

つまり
a += [3]
はaに格納されていたlistそのものを改変して要素をくっつける意味になっています。tupleと異なりlistはa += [3]a = a + [3]の振る舞いが違っているのですね。

これはpythonの言語仕様がそうなっているわけではなくlistの__iadd__メソッドが

いやーわざわざ新しいlistインスタンスつくるのメモリーがもったいないし、自分自身の箱(要素を保持しておく場所)をぐいっと伸ばして+=の右側に指定したlistの中身をそこへ代入しちまえばいいやー!

といった定義になっているのです。これはlistのextendメソッドでも同じようなことができます。
a.extend([3])

tupleは絶対に自分自身を書き換えません。「tupleの値 + tupleの値」という演算をすると毎回新たなtupleを作り出しているのですね。それゆえextendのようなメソッドもありません。

見かけ上listもtupleも
a += b
で連結できるかのように感じますが、listは一々新たなインスタンスを生成しないのに対してtupleで上記のようなことをやっても毎回新たなインスタンスを計算しているわけでlistに比べて効率が若干悪くなります。

def foo(a, b, n):
    for _ in range(n):
        a += b

def run(f):
    import time
    t = time.time()
    f()
    return time.time() - t

run(lambda : foo([1, 2, 3], [1, 2, 3], 1000))  # 0.00011658668518066406
run(lambda : foo((1, 2, 3), (1, 2, 3), 1000))  # 0.004464626312255859


(訂正:コピペミスで2番目のrunの引数をtupleじゃなくてlistかのように書いていました。訂正してお詫びいたします。)
この例ではlistの方がtupleより一けた早いことがわかります。ただちいさな要素数のものをちょこっと連結するだけなら、こんな点をそう気にする必要もないと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/31 19:55

    ありがとうございます😊
    たしかに、見かけ上はリストもタプルもそれぞれ連結できるからほぼ同じといっても過言じゃないなと認識しますが

    タプルは最初に言ったことは断固として変えない頑固親父みたいな感じで、リストは最初に言ったことを誰かに指摘されたり補足してもらうと『そうなんだ』とアップグレードしなおして発言する母のような感じですね。(例えとして良いのかわかりませんが)

    キャンセル

  • 2018/05/31 19:59

    まさにそういう理解でよいと思います~
    断固として値を変えないおやじにはよい点があり、他のメソッドの引数にどうわたそうが呼び元では「この値は絶対に変わらない」と安心できることです。頑固なのはときとして貴重な利点になるといえるでしょう。

    キャンセル

  • 2018/05/31 20:20

    本当に勉強になります!😊

    キャンセル

+5

解決済みの質問ですが・・・

pythonのオブジェクトには固有のidが割り振られています。同じオブジェクトならidが変わることはありませんし、同時に存在する異なるオブジェクトが同じidになることもありません。CPython(普通に使われているpythonです)の実装では、idはメモリ上のアドレスと等価です。

2. 組み込み関数 — Python 3.6.5 ドキュメント

idは組み込み関数id()で確認できます。これを使うと簡単に「listとtupleの違い」を確認することができます。

>>> lst = [1,2,3]
>>> id(lst)
139687300282696
>>> lst += [4,5,6]
>>> id(lst)
139687300282696  # 変わらない
>>> tup = (1,2,3)
>>> id(tup)
139687181137384
>>> tup += (4,5,6)
>>> id(tup)
139687181105000  # 変わった

「結果は同じようなものなんだから、どっちを使っても良い?」という話もありますが、あまり良くないです。
元の変数とは別に、同じものを参照する変数を用意するとすぐわかります。

>>> lst = [1,2,3]
>>> lst_ref = lst
>>> lst += [4,5,6]
>>> lst
[1, 2, 3, 4, 5, 6]
>>> lst_ref
[1, 2, 3, 4, 5, 6]
>>> tup = (1,2,3)
>>> tup_ref = tup
>>> tup += (4,5,6)
>>> tup
(1, 2, 3, 4, 5, 6)
>>> tup_ref
(1, 2, 3)

この違いは常に意識しておかないと、危ないと言えます。参照(ポインタみたいなもの:すべての実体は参照によって示される以外の方法では存在しない)と実体(いわゆるインスタンス)がどう結びついているのかをしっかり理解しないと、まともに動くコードは書けません。
ま、オブジェクト指向言語って、そういうものです。

それと、より実際的な問題として、listは辞書のキーやsetの要素になれません。tupleはなれます。
この違いはmutable(可変)かimmutable(不変)かによるものです。
まあ、辞書のキーにリストが使えたら、キーに直接appendするだけでえらい騒ぎになってしまいますから・・・

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+4

『要素が変更できない』とは、つまり次のような違いです。

>>> lst = [1, 2, 3, 4, 5]
>>> lst[0] = 42
>>>
>>> print(lst)
[42, 2, 3, 4, 5]
>>> tpl = (1, 2, 3, 4, 5)
>>> tpl[0] = 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>
>>> print(tpl)
(1, 2, 3, 4, 5)

実際には、次のような使い分けがあるような。

  • 同じ型のオブジェクトを扱う ⇒ リスト
  • 違う型のオブジェクトを扱う ⇒ タプル

リストは配列、タプルは構造体に近い使われ方をしているように思います。

タプルはリストと似ていますが、たいてい異なる場面と異なる目的で利用されます。タプルは不変型 (immutable) で、複数の型の要素からなることもあり、要素はアンパック(この節の後半に出てきます)操作やインデックス (あるいは namedtuples の場合は属性)でアクセスすることが多いです。一方、リストは変更可能 (mutable) で、要素はたいてい同じ型のオブジェクトであり、たいていイテレートによってアクセスします。

引用元: Python チュートリアル » タプルとシーケンス

参考

英語ですけれど、深まった議論がなされています。
Stack Overflow - What's the difference between lists and tuples?

Apart from tuples being immutable there is also a semantic distinction that should guide their usage. Tuples are heterogeneous data structures (i.e., their entries have different meanings), while lists are homogeneous sequences. Tuples have structure, lists have order.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/31 19:23

    ありがとうございます!

    別の質問かもしれませんが、
    a = (1, 2, 3)
    とだけ入力した際
    aはリストなのかタプルなのかがわかりません。

    キャンセル

  • 2018/05/31 19:26

    それはタプルですね。
    リストなら a = [1, 2, 3] と書きます。

    なお、実は a = 1, 2, 3 とも書けます。これはタプルです。

    キャンセル

  • 2018/05/31 19:30

    type(a)で確認できますよ。
    In [1]: a = (1, 2, 3)
    In [2]: type(a)
    Out[2]: tuple
    となりました。

    キャンセル

  • 2018/05/31 19:38

    なるほど!ありがとうございます😊
    そもそもの書き方ですね。
    リストは[ ]
    タプルは( ) or 無
    ということでしょうか?

    キャンセル

  • 2018/05/31 19:41

    @ikapy さん
    補足ありがとうございます。

    @gontaros0302 さん
    基本的には、リストは[ ]、タプルは( ) です。
    ( )が省略できる場面がたまにあり、積極的に利用しなければならないわけではありませんが、知っておくと何かと便利です。

    キャンセル

  • 2018/05/31 19:42

    ということですね。

    キャンセル

  • 2018/05/31 19:48

    @ikapy さん
    ありがとうございます😆

    @LouiS0616 さん
    丁寧に解説していただき、ありがとうございます😊

    キャンセル

+1

【インデックス】を指定した【中身】の書き換えは不可能という認識でいいと思います。

全体の書き換えは出来ます。

x = (0, 1, 2)
x = 10
print(x) #10
x = (0, 1, 2)
x += (3, 4, 5)
print(x)#(0, 1, 2, 3, 4, 5)
x = (0, 1, 2)
x[0] = 1 #エラー

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/31 19:25

    なるほど、わかりやすい回答ありがとうございます。段ボール箱にみかん、りんご、桃が入っていたら、追加でキウイいれたりバナナを入れることはできるけれど、りんごをナシに変更するのはダメだよってことですね。

    キャンセル

  • 2018/05/31 19:57

    概ねそんな感じですが厳密には少し異なります。
    こんがらないように言わないべきかと思いましたが
    既に他の回答者さんがそれらしき事に触れているので一応

    リストにみかん、りんご、桃を入れた後にキウイやバナナを入れるとします(appendを使って)。当然ですが今ある段ボールに対してそのまま追加でいれます。
    しかしタプルで追加した場合は、一度わざわざ段ボールを潰し、入ってあった果物を全て捨ててから新たに段ボールを用意して、果物を入れていきます。
    自身を書き換えないというのはそういう事で
    パフォーマンスが低下する事があるのもその為です。

    一見奇妙に感じるかもしれませんが、そうした方がバグを生みにくかったりするのです。

    キャンセル

  • 2018/05/31 20:18

    一度オジャンにするんですねー。
    本当にtupleは頑固ですね。。笑

    キャンセル

  • 2018/05/31 20:29

    というよりリストや辞書を除いてpythonの型は大体そんな感じになっています。str型・int型・float型・tuple型 この辺りは新しい物を作る時は、段ボールを一度潰してから的な事をやっています。
    まあもう既に解決済みなのでこの辺でw

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    8041questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。