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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

3回答

3006閲覧

python listを変数に分解する際の.appendメソッドにおけるバグについて

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1グッド

0クリップ

投稿2018/08/22 10:29

初心者です。

あるリストにタプルの要素を複数回加えようとした場合に起こる挙動について教えて頂けませんか?

詳しいソース全文は載せませんが、
pythonである時系列データcsvにて用意し
サンプリング単位でリスト化しました。

python

1def cal() 2 nv = tuple([nvx1 ,nvy1 ,nvx2 ,nvy2 ,nvx3 ,nvy3 ,nvx4 ,nvy4 ,nvx5 ,nvy5 ,nvx6 ,nvy6 , 3       nvx7 ,nvy7 ,nvx8 ,nvy8 ,nvx9 ,nvy9 ,nvx10,nvy10,nvx11,nvy11,nvx12,nvy12, 4       nvx13,nvy13,nvx14,nvy14,nvx15,nvy15,nvx16,nvy16,nvx17,nvy17...])

その後複数の要素を含んだタプルをいくつか作成し、
返り値としてnvを指定した後、

別の関数内でbという変数を定義しnvの各項目を呼び出そうと考えました。

python

1def other() 2 nv = cal() 3 b1 = b2 = b3 = ... = b100 = [] 4 b1.append(nv[0]),b2.append(nv[1]),b3.append(nv[2]),b3.append(nv[3])....b100.apend(nv[99])

のように他の変数にそれぞれタプルの中身をappendしようとすると
b1にもb2にもb3共通してnv[0..99]が全て追加されていました。

python

1>b1 = (nv[0],nv[1],nv[2],nv[3]....nv[99]) 2>b2 = (nv[0],nv[1],nv[2],nv[3]....nv[99]) 3>b3 = (nv[0],nv[1],nv[2],nv[3]....nv[99]) 4. 5. 6. 7

またappendの数を減らすと追加する要素数も増減することが分かりました。

python

1 2def other() 3 nv = cal() 4 b1 = b2 = b3 = ... = b100 = [] 5 b1.append(nv[0]),b2.append(nv[1]),b3.append(nv[2]),b3.append(nv[3]) 6 7 >b1 = (nv[0],nv[1],nv[2],nv[3]) 8 >b2 = (nv[0],nv[1],nv[2],nv[3]) 9 >b3 = (nv[0],nv[1],nv[2],nv[3]) 10 11

対処法は様々な方法があることは理解しているため
appendの仕組みやなぜこのようなことが起こるのか知りたいです。

説明が分かりにくくて申し訳ありませんがご助言頂けると幸いです。

tachikoma👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

多くの初学者がハマるので、『Python リスト コピー』などと検索すれば解説は多く見当たります。

例えばこれ: Qiita - リストのコピーでハマった話
shiracamusさんの図解コメントも参考になるでしょう。


本題から逸れますが、連番の変数名を必要とする場合は総じて設計が悪いです。
辞書やリストなどのコレクションを適宜利用し、ループで対処しましょう。

投稿2018/08/22 10:43

LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

pythonのオブジェクトはすべて参照型ということを頭に入れておく必要があります。C言語でいうvoidポインタみたいなものです。

ですから、当然ながら代入も「参照の代入」です(束縛と言った方が良いかもしれない)。

python

1b1 = b2 = b3 = ... = b100 = []

という代入文がどう処理されるかというと、ざっくり説明すると

  1. []がインスタンス化される
  2. b1,b2,b3,...,b100という変数がそのインスタンスを参照するようになるように処理される

という流れです。

すべて同じオブジェクトなのは当然の結果。

参考:Pythonの、変数と代入についての誤解を解く - naritoブログ


別のオブジェクトにする方法としては、

python

1b1 = [] 2b2 = [] 3... 4b100 = []

というのが一つありますが、まあ合理的なプログラミングではありません。とりあえずリストに入れて管理することにすると、

python

1blist = [] 2for _ in range(100): 3 blist.append([])

こんな感じでしょうかね。indexを一つずらして使ってください。b1はblist[0]に該当します。

これは内包表記にできるので、下のようにすることもできます。

python

1blist = [[] for _ in range(100)]

投稿2018/08/22 12:49

編集2018/08/22 12:53
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly

pythonを使う上で避けて通れないものですね。

代入を可視化してみた。
https://goo.gl/iXEoZQ

投稿2018/08/22 22:51

mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問