teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

追記

2019/12/15 17:32

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -1,4 +1,97 @@
1
1
  people_listの要素(people_1、people_2…)を取り出したいのであれば、`people_list[-1]`や`people_list[-2]`のようにすればよいのではないでしょうか。それで問題なく`["Mike", "Bob", "Ted", "Jeff"]`, `["Ken", "Mic", "Chris"]`が得られるかと思います。
2
2
 
3
3
  # もしかして
4
- `people_1`のような「文字列」を得たいのでしょうか? そういうことはできません。変数名はソースコード上だけで存在する記号のようなものです。実行時に拾うことはできません。
4
+ `people_1`のような「文字列」を得たいのでしょうか? そういうことはできません。変数名はソースコード上だけで存在する記号のようなものです。実行時に拾うことはできません。
5
+
6
+ # 誤解しているであろうこと
7
+ たとえば
8
+
9
+ ```python
10
+ a = 10
11
+ print(a)
12
+ ```
13
+
14
+ としたとき、表示されるのは`a`ではなく`10`であるということは理解できると思います。
15
+
16
+ 同様に
17
+
18
+ ```python
19
+ a = 10
20
+ lst = [a]
21
+ ```
22
+
23
+ では`lst`変数に結びついているオブジェクトはリテラルで書けば`[10]`です。
24
+
25
+ ではなんでそうなるのか。このコードの動作をおおまかに追ってみます(厳密に正確ではありません)。わかりやすいように行ごとに分けます。
26
+
27
+ (再掲)
28
+ ```python
29
+ a = 10
30
+ lst = [a]
31
+ ```
32
+
33
+ - 一行目
34
+ 0. 構文解析して代入文であること、左辺が`a`という識別子であること、右辺が`10`という整数値のリテラルであることを認識する
35
+ 0. 右辺の`10`というリテラルを「評価」し、対応する`int`型のオブジェクトをメモリ上に生成する
36
+ 0. 左辺の`a`という変数を新たに作り、上で生成した`int`型のオブジェクトへの参照と`a`を結びつける
37
+
38
+ - 二行目
39
+ 0. 構文解析して代入文であること、左辺が`lst`という識別子であること、右辺が`[a]`という「`a`という式(識別子)を単一の要素として持つリストのリテラル」であることを認識する
40
+ 0. 右辺の`[a]`を「評価」する。
41
+  そのためにまず内側にある`a`という式を「評価」する。識別子なのがわかっているので同名の変数を探し、一行目で定義されている`a`であるとわかる。この`a`に結び付けられたオブジェクト(への参照)が評価した結果になる。
42
+ 次に外側のリストオブジェクトを一行目と同様に生成し、その0番目の要素に先程`a`を評価した結果を格納する。
43
+ 0. 一行目の最後と同様にリストオブジェクトへの参照を変数`lst`に結びつける
44
+
45
+ これだけで理解しろというのも酷なのでもう少しわかりやすく書くと、二行目のところはまず`[a]`が`[10]`になってから`lst`という変数に代入されるイメージです。要するに変数名の情報などリストオブジェクトは持っていないのです。
46
+
47
+ # ならどうするのか
48
+ 基本的に、多くのプログラミング言語は「ただの変数名」に対して何らかの処理を行うようにはできていません。変数名はソースコードを見やすくするために存在している記号のようなものです。「`print(a)`のときには`a`という情報が`print`関数に渡される!」と考えるかもしれませんが、渡されているのは`a`を評価した結果として得られるオブジェクトであり、どんな変数名に入っていたのかというような情報は一切存在しません。
49
+
50
+ Pythonのプログラミングで操作の対象にするデータは基本的に、オブジェクトとしてPythonインタプリタが作動するメモリ空間上に存在している必要があります。「名前」を扱いたければ、通常は文字列型オブジェクトを用いると良いでしょう。
51
+
52
+ ```python
53
+ people_list = ["people_8", "people_7", "people_6", "people_5", "people_4", "people_3", "people_2", "people_1"]
54
+ for name in people_list:
55
+ print(name)
56
+ ```
57
+ これで質問文の「↓こんな答えがほしいです。」が得られます。やった!
58
+
59
+ ……たぶんこれは得たい結果ではないでしょう。`["Mike", "Bob", "Ted", "Jeff"]`, `["Ken", "Mic", "Chris"]`など(を評価した結果のオブジェクト)を`people_list`から得る手段は失われました。何をしても`"people_1"`や`"people_2"`など(を評価した結果のオブジェクト)しか得られません。それはそういうものだからですね。
60
+
61
+ えーっと、やりたいことはたぶん名前と値を紐付けて記憶することでしょう。できなくはありません。リスト型ではできませんが、辞書型を使うとできます。
62
+
63
+ ```python
64
+ people_dict = {"people_8":people_8, "people_7":people_7, "people_6":people_6, } # 6以降省略
65
+ ```
66
+
67
+ これで`people_dict.keys()`とでもすればキーの一覧が、`people_dict.values()`で値の一覧が得られます。両方セットで得たければ`people_dict.items()`が使えます。
68
+ (すべてビューオブジェクトという特殊なiterableです)
69
+ ```python
70
+ for key in people_dict.keys():
71
+ print(key)
72
+ ```
73
+
74
+
75
+ ただし、私が書くなら最初からこんな手間はかけずに、
76
+
77
+ ```python
78
+ people_dict = dict()
79
+ people_dict[0] = ["Mike", "Bob", "Ted", "Jeff"]
80
+ people_dict[1] = ["Ken", "Mic", "Chris"]
81
+ # ...
82
+ ```
83
+ とでもしておくでしょう。0から始まる添字にするのはプログラミング上で扱いが楽だからで、0,1,2を必要に応じてpeople_1, people_2, people_3のような文字列に変換することは実際難しくありません(とても容易です)。なお、要素数が予めわかっているなら、辞書の代わりに`[None]*8`のようなリストを使っても構いませんし、あるいはいっそのこと
84
+
85
+ ```python
86
+ people_list = [["Mike", "Bob", "Ted", "Jeff"],
87
+ ["Ken", "Mic", "Chris"],
88
+ # ...
89
+ ]
90
+ ```
91
+ のように最初に定義してしまうのだって手です。
92
+
93
+
94
+
95
+ # まとめ
96
+ - 変数名をプログラムから扱うことは通常できない
97
+ - 連番の変数名にするのではなく、最初からプログラムでハンドリングしやすいデータ構造を考えるべき

1

追記

2019/12/15 17:31

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -1,1 +1,4 @@
1
- people_listの要素(people_1、people_2…)を取り出したいのであれば、`people_list[-1]`や`people_list[-2]`のようにすればよいのではないでしょうか。それで問題なく`["Mike", "Bob", "Ted", "Jeff"]`, `["Ken", "Mic", "Chris"]`が得られるかと思います。
1
+ people_listの要素(people_1、people_2…)を取り出したいのであれば、`people_list[-1]`や`people_list[-2]`のようにすればよいのではないでしょうか。それで問題なく`["Mike", "Bob", "Ted", "Jeff"]`, `["Ken", "Mic", "Chris"]`が得られるかと思います。
2
+
3
+ # もしかして
4
+ `people_1`のような「文字列」を得たいのでしょうか? そういうことはできません。変数名はソースコード上だけで存在する記号のようなものです。実行時に拾うことはできません。