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

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

新規登録して質問してみよう
ただいま回答率
85.48%
オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Python

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

1624閲覧

dict_keyにタプルが使われた際の、そのタプル要素へのアクセス方法。

MAMOMIMOMU

総合スコア13

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Python

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/01/01 11:26

前提・実現したいこと

pythonで、最小値を求めるコードを書きたいです。

発生している問題・エラーメッセージ

地点を入力すると、予め辞書に登録されている県庁所在地のうち
最も近い地点を返してくれるプログラムを次のように書きました。

python

1pref_capitals = {(43.06417, 141.34694): "北海道(札幌)", 2 (40.82444, 140.74): "青森県(青森市)", 3 (39.70361, 141.1525): "岩手県(盛岡市)"} 4 5loc = tuple(map(float, input().split())) 6min_calc = None 7min_value = "" 8 9for key in pref_capitals.keys(): 10 calc = (key[0] - loc[0])**2 + (key[1] - loc[1])**2 11 if min_calc == None: 12 min_calc = calc 13 14 if min_calc > calc: 15 min_calc = calc 16 min_value = pref_capitals[key] 17 18print(min_value)

Pythonでは、

python

1 if min_calc == None: 2 min_calc = calc

のような断りを入れるのが自然のようなのですが、
このようにせず、同じことではあるのですが、
イテレータの最初の要素の計算を先にmin_calcに入れる
以下のようなコードを書きました。

python

1pref_capitals = {(43.06417, 141.34694): "北海道(札幌)", 2 (40.82444, 140.74): "青森県(青森市)", 3 (39.70361, 141.1525): "岩手県(盛岡市)" 4 } 5loc = (41, 141) 6min_calc = (pref_capitals.keys()[0] - loc[0])**2 + (pref_capitals.keys()[1] - loc[1])**2 7 8for key in pref_captals.keys(): 9 calc = (key[0] - loc[0])**2 + (key[1] - loc[1])**2 10 if min_calc > calc: 11 min_calc = calc 12print(min_calc)

エラー

error

1TypeError: 'dict_keys' object is not subscriptable

するとこのようなエラーが出てしまいます。

原因

原因は明らかで、辞書の中のキーであるタプルへのアクセスの仕方が間違っているのですが、
調べてもどう表現すれば良いのか見つけることができませんでした。

python

1your_dictionary[0][0]

でもダメですし、どうすれば良いのでしょう?

また、なぜdict_key型のオブジェクトは、上記のような方法で要素にアクセスできないのでしょう。
何か理由と言いますか、できるようにしなかった特別な理由などございましたら
教えていただきたいです。

よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

面白くもなんともない方法で解決。

python

1 2pref_capitals = {(43.06417, 141.34694): "北海道(札幌)", 3 (40.82444, 140.74): "青森県(青森市)", 4 (39.70361, 141.1525): "岩手県(盛岡市)" 5 } 6loc = (41, 141) 7keys = list(pref_capitals.keys()) # listにすればいい 8min_calc = (keys[0][0] - loc[0])**2 + (keys[0][1] - loc[1])**2 9 10for key in keys: 11 calc = (key[0] - loc[0])**2 + (key[1] - loc[1])**2 12 if min_calc > calc: 13 min_calc = calc 14print(min_calc)

また、なぜdict_key型のオブジェクトは、上記のような方法で要素にアクセスできないのでしょう。
何か理由と言いますか、できるようにしなかった特別な理由などございましたら
教えていただきたいです。

そもそもPythonの辞書には伝統的に要素の順番の概念がありませんでした。{"a":1, "b":2}{"b":2, "a":1}は過去のある時点では全く同じ意味でしたし、要素の順番がそれなりに自然に扱えるように(挿入した通りの順序で取り出せるように)正式になったのはPython3.7以降です。

順番が定まらなければインデックスも定まりませんから、なくて当然です。辞書キーのビューオブジェクトに限った話ではなく、そもそも辞書からキーや値をインデックスで取ることができません。

もっとも、最新のPythonの辞書は順序付きになってしまいましたから昔の仕様にこだわらなくても良い理由はできている訳で、将来的にはこの辺りの仕様も変わる可能性はあります。Python4とかで。
(といっても、それを実装するために辞書の要素アクセスに余計なオーバーヘッドが増える可能性もあり、それを増やしてまでやるかというと、やらないでしょう。辞書型はそのまま名前空間の実装に使われている型ですから、ある意味Pythonで一番重要で使用頻度の高い型です)

投稿2020/01/01 13:43

hayataka2049

総合スコア30933

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

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

MAMOMIMOMU

2020/01/01 14:34

ご丁寧な解答ありがとうございました。 まさに仰られたことはどこかで読んだことがあります。 とても附に落ちました。
guest

0

ベストアンサー

Python

1min_calc = (list(pref_capitals.keys())[0][0] - loc[0])**2 + (list(pref_capitals.keys())[0][1] - loc[1])**2 2#4.381165152499981

投稿2020/01/01 12:10

meg_

総合スコア10580

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

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

MAMOMIMOMU

2020/01/01 15:36

簡潔に適切なご回答ありがとうございます。 確かにリストに変換すれば良さそうですね。
guest

0

一番近い、距離が一番小さい、min関数の出番。

pref_capitals = {(43.06417, 141.34694): "北海道(札幌)", (40.82444, 140.74): "青森県(青森市)", (39.70361, 141.1525): "岩手県(盛岡市)" } loc = (41, 141) nearest = min(pref_capitals, key=lambda geo: (loc[0] - geo[0])**2 + (loc[1] - geo[1])**2) print(nearest, pref_capitals[nearest])

元のやり方なら、keysのイテレータを作って、nextで最初の要素を取り出して仮の最小値にして、残りのkyesでループするのが楽です。

pref_capitals = {(43.06417, 141.34694): "北海道(札幌)", (40.82444, 140.74): "青森県(青森市)", (39.70361, 141.1525): "岩手県(盛岡市)" } loc = (41, 141) keys = iter(pref_capitals.keys()) key = next(keys) min_calc = (key[0] - loc[0])**2 + (key[1] - loc[1])**2 for key in keys: calc = (key[0] - loc[0])**2 + (key[1] - loc[1])**2 if min_calc > calc: min_calc = calc print(min_calc)

投稿2020/01/01 11:51

編集2020/01/01 12:34
shiracamus

総合スコア5406

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

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

MAMOMIMOMU

2020/01/01 15:37

とても勉強になります。 nextなどまだやっていない概念なのですが、 調べて参考にさせていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問