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

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

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

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

Q&A

解決済

2回答

3047閲覧

【python】リストと辞書のenumerate()と.items()メソッドについて

owata114514

総合スコア13

Python

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

0グッド

0クリップ

投稿2018/12/02 07:22

何でリストの場合はリスト名をメソッドの引数に書いて、辞書の場合は辞書名をドットでつなぐ(オブジェクトにする?)のですか?
また、リスト名と辞書名は独立ではないのになぜメソッドを分けているのでしょうか?

enemies = ["スライム","ドラゴン","魔王"]
for i,enemy in enumerate(enemies):
print(i,enemy)

0 スライム
1 ドラゴン
2 魔王

enemies = {0:"スライム",1:"ドラゴン",2:"魔王"}
for i,enemy in enemies.items():
print(i,enemy)

0 スライム
1 ドラゴン
2 魔王

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

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

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

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

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

guest

回答2

0

大前提として、

python

1enemies = ["スライム","ドラゴン","魔王"] 2for i,enemy in enumerate(enemies): 3 print(i,enemy) 4""" 50 スライム 61 ドラゴン 72 魔王 8""" 9 10enemies = {0:"スライム",1:"ドラゴン",2:"魔王"} 11for i,enemy in enemies.items(): 12 print(i,enemy) 13 14""" 150 スライム 161 ドラゴン 172 魔王 18"""

両者はまったく違う処理です。たまたまprintされる結果が同じというだけで。

{0:"スライム",1:"ドラゴン",2:"魔王"}{"a":"スライム","b":"ドラゴン","c":"魔王"}にしても別に構わないが、リストの方はこれはできない、ということがわかれば、理解できると思います。リストはindexと値を対応付けるデータ構造で、辞書はキーと値が結びついたデータ構造です。

enumerateは型としてはクラスで、enemiesenumerateのコンストラクタに渡されます。もしenumeratelistのメソッドだと思っているのなら、間違いです。enumerateはグローバル名前空間に束縛された組み込み型です(厳密にはもう少し複雑な仕組みなのですが、アバウトに言えばそうです)。

enemies.items()は辞書のインスタンスに対するdict.itemsの呼び出しです。

なので、両者はまったく別物だし、実は私などは見た瞬間「まったく違うコードだろう」と認識してしまうので、質問者様の疑問をあまりよく理解できていません。なので、もしかしたら的はずれなことを書いているかもしれませんが、ご容赦ください。


何でリストの場合はリスト名をメソッドの引数に書いて、辞書の場合は辞書名をドットでつなぐ(オブジェクトにする?)のですか?

上で書いたとおり、enumerateはメソッドでもなんでもありません。辞書の場合、ドットでつなぐことでオブジェクトにしている訳でもありません。強いて言えばdict.itemsというメソッドオブジェクトをcallしているだけです。

また、リスト名と辞書名は独立ではないのになぜメソッドを分けているのでしょうか?

いえ、両者は完全に独立したコードです。それぞれ別に動かしてもちゃんと動きます。

投稿2018/12/02 08:53

hayataka2049

総合スコア30933

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

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

0

ベストアンサー

何でリストの場合はリスト名をメソッドの引数に書いて、辞書の場合は辞書名をドットでつなぐ(オブジェクトにする?)のですか?

『そういう設計だから』というと元も子もないですかね。
こんな関数も作れるわけですし。

Python

1def items(dct): 2 return dct.items()

ドキュメントでは、次のように説明されています。

Python にメソッドを使う機能 (list.index() 等) と関数を使う機能 (len(list) 等) があるのはなぜですか?

主な理由は歴史です。複数の型に対しての総称的な操作で、対象のオブジェクトがメソッドを全く持っていなかった (例えば、タプル) としても働くよう意図したものに関数は使われました。Python の関数的機能 (map() 、zip() など) を使うときに、型のはっきりしないオブジェクトのコレクションに対して、難なく適用できる関数があるのも便利なことです。

引用元: Python よくある質問 » デザインと歴史 FAQ

確かにenumerateの引数はイテラブルなら何でも良いですから、
リストのメソッドとして定義する必然性は無いのだ、と納得できます。

また、リスト名と辞書名は独立ではないのになぜメソッドを分けているのでしょうか?

enumerateは、start引数を指定すれば開始番号を自在に変更できます。

Python

1>>> enemies = ["スライム", "ドラゴン", "魔王"] 2>>> for i, enemy in enumerate(enemies, start=100): 3... print(i, enemy) 4... 5100 スライム 6101 ドラゴン 7102 魔王

また、引数がリストでなければいけないというわけでもありません。

Python

1>>> for i, ch in enumerate('spam'): 2... print(i, ch) 3... 40 s 51 p 62 a 73 m

dict.itemsがインデックスを含んだタプルを返すのは、
今回たまたまそのようなキーが用いられていたというだけです。

Python

1>>> enemies = {"弱": "スライム", "中": "ドラゴン", "強": "魔王"} 2>>> for k, enemy in enemies.items(): 3... print(k, enemy) 4... 5弱 スライム 6中 ドラゴン 7強 魔王 8>>> 9>>> for i, enemy in enumerate(enemies.values()): 10... print(i, enemy) 11... 120 スライム 131 ドラゴン 142 魔王

投稿2018/12/02 07:43

編集2018/12/02 09:01
LouiS0616

総合スコア35660

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

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

owata114514

2018/12/02 08:41

回答ありがとうございます。納得しました。 加えて関数とメソッドを混同していたこともわかりました。 > また、リスト名と辞書名は独立ではないのになぜメソッドを分けているのでしょうか? 上の例にあるenemiesには辞書を追加した時点でそれまであったリストは上書きされますよね enemiesがまた新しく作られてリストと辞書の2つが独立して存在してるなら、どっちかを特定するために分けなければいけないとは思いますが、1つしかないのになぜ分ける必要があるのか分かりません 要素を削除するpopメソッドのenemies.pop()のように(enemiesがリストの場合はインデックスを、辞書の場合はキーを引数にする)共通したメソッドでできるほうが楽だと思います(メソッドにする必要がないのであればどちらもenumerate関数で)
LouiS0616

2018/12/02 09:02 編集

オブジェクトを同じように操作しても、その型に依って動作が異なることを多態性(ポリモーフィズム)と言います。 owata114514さんが『共通したメソッドでできるほうが楽』だと思われるのは、オブジェクト指向的に洗練された感覚だと思います。 ただ、enumerateとdict.itemsは動作があまりにかけ離れています。 理由に関しては、ちょっと長くなったので回答に追記しました。
hayataka2049

2018/12/02 08:57

横槍失礼します。 >enemiesがまた新しく作られてリストと辞書の2つが独立して存在してるなら、どっちかを特定するために分けなければいけないとは思いますが、1つしかないのになぜ分ける必要があるのか分かりません オブジェクトは「リスト」と「辞書」の両方存在します。名前が1つしかないだけで。オブジェクトのidを見ればすぐわかります。 >>> enemies = ["スライム","ドラゴン","魔王"] >>> id(enemies) 140084757169416 >>> enemies = {0:"スライム",1:"ドラゴン",2:"魔王"} >>> id(enemies) 140084757828360 pythonの変数は「オブジェクトを特定するための名前」みたいなもので、任意のオブジェクトと好きなだけ結びつけることができます。代入文が実行されると、右辺が評価されてオブジェクトが得られ、そのオブジェクトが左辺の名前に結び付けられる、という仕組みです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問