アプリ版:「スタンプのみでお礼する」機能のリリースについて

Python入門サイトの説明不足で私は悪くありません。
私の理解力がないわけではありません。

定義、呼び出し、結果から推測するに
呼び出しの第二引数から変数=代入まで*argumentsに文字列が入ってますが
例えば*a,*bと関数を定義した場合どのように*aと*bの判断するのでしょうか?
def cheeseshop(*a,*b)
cheeseshop("aaaaaaa","iiiiiiiiii","uuuuuuuu","eeeeeeeee","oooooo")

**keywords(ポインタのポインタ)は変数名と文字列を引き込んでますよね?
keysで変数名を引き出しsortedで昇順ソート
そして、ここからが難解なのですが
for kw in keys:
print(kw, ":", keywords[kw])
kwにkeysの文字列を代入しているのはわかりますが
keywords[kw]はどんな動きをしているのですか?
最初のループではkeywords["Michael Palin"]ってことですよね?わけが分かりません。

明らかに前提知識が不足していますがpython3の入門サイトが
http://docs.python.jp/3/tutorial/controlflow.htm …
以外見つからず悪戦苦闘してます。


#定義
def cheeseshop(kind, *arguments, **keywords):
print("-- Do you have any", kind, "?")
print("-- I'm sorry, we're all out of", kind)
for arg in arguments:
print(arg)
print("-" * 40)
keys = sorted(keywords.keys())
for kw in keys:
print(kw, ":", keywords[kw])

#呼び出し!
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")


#結果
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch

A 回答 (3件)

ええと、まずは。



> **keywords(ポインタのポインタ)は変数名と文字列を引き込んでますよね?

引き込んでません。
と言うか、大前提として、Pythonには「ポインタ」がないのです(笑)。

実はこの * とか ** とか言うのはC言語で言うポインタじゃなくって、可変長引数とその仲間だ、と言う意味です。

*の使用例:

>>> def foo(*a):
    return a

>>> foo(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5) # a に与えられた引数はタプルとして表現される
>>>

上のように、引数aを指定してても、これは*で可変長引数だ、と言ってるので、引数は(理論上は)何個でもツッコんで大丈夫だ、って事です。

一方、**は次のような「キーワード引数」(C言語にはない)と言う指定です。
これは、またもや「C言語だとわざわざ実装しなきゃいけない」ハッシュテーブル(Pythonでは辞書型と呼ぶ)への引数として機能します。

>>> def bar(**b):
    return b

>>> bar(教えて="goo", OK="WAVE")
{'教えて': 'goo', 'OK': 'WAVE'} # Pythonのハッシュテーブルの表記

教えて="goo"と言う指定がハッシュテーブルのキー、'教えて'とその値'goo'、OK="WAVE"と言う指定が'OK'と言うハッシュテーブルのキー、'WAVE'がその値になってるのが分かるでしょうか。

この辺は次の部分をお読み下さい。

キーワード引数:
http://docs.python.jp/3/tutorial/controlflow.htm

任意引数リスト:
http://docs.python.jp/3/tutorial/controlflow.htm

> for kw in keys:
   print(kw, ":", keywords[kw])
> kwにkeysの文字列を代入しているのはわかりますが
> keywords[kw]はどんな動きをしているのですか?

んー、なるほど、ちょっとC言語なんかに比べるとちょっと高度な事やってるかもしれませんね。
まず大前提としては。構文は似てるんですが、PythonのforはC言語のforとはちょっと違うんです。こいつはイテレータ(繰り返し機能)を呼び出しす役目を担っていて、実は「繰り返し要素」を持ってるのはデータ型(この場合はkeysと言うリスト)に含まれてる「イテレータ」の方なんですね。

先ほど見ましたが、Pythonでのハッシュテーブル、辞書型自体が「イテレータ」としての情報を持っています。
キーワード引数によって与えられた引数は、このコードの場合、内部的には次のような「辞書型」を持つようになっています。

keywords = {'shopkeeper': 'Michael Palin', 'client': 'John Cleese', 'sketch': 'Cheese Shop Sketch'}

Cでハッシュテーブルの実装経験があるのでしたら、先ほどにも説明した通り、

キー: 値

の組が3つ、keywordsと言うハッシュテーブルに入っています。
ここからキーだけを取り出すメソッド(C++で言うとメンバ関数)が、keys()です。

>>> keywords.keys()
dict_keys(['shopkeeper', 'client', 'sketch'])

ハッシュテーブルのキーだけが取り出されていますね。
んで、ハッシューテーブルは、繰り返しますが、Cでの実装経験がおありでしたら、「データの格納方法」はアルゴリズム上での「任意」で、順番は保証されていません。これは検索用データ構造、って前提から言ったらオーケーで、要は検索して速く値を返すのがハッシュテーブルの本懐で、「データ格納の順番は重要ではない」と言う事の裏返しです。
従って、キーを取り出してもそいつが「アルファベット順に整然とならんでる」保証がないんですね。だからソートしてるんです。

>>> keys = sorted(keywords.keys())
>>> keys
['client', 'shopkeeper', 'sketch']

そして、Pythonでのハッシュテーブルでの値の取り出し方、です。
これはCの配列の参照のような形式で書きます。

>>> keywords['client']
'John Cleese'
>>> keywords['shopkeeper']
'Michael Palin'
>>> keywords['sketch']
'Cheese Shop Sketch'
>>>

ハッシュテーブルkeywordsにキーを与えたらその値が返ってきてるのが分かるでしょう。
そうすれば、

keys = sorted(keywords.keys())
for kw in keys:
  print(kw, ":", keywords[kw])

と言うのは

1. キーワードからキーだけ取り出して、アルファベット順にソートしたリストkeysを作る
2. リストkeysに含まれてる要素(取り敢えずkwと呼ぶ)に対して

  「keysに含まれる要素(kw), ":" ハッシュテーブルからkwに対する値を呼び出し」

を順繰りに印字せよ

となってるのが分かるのではないでしょうか。

多分Pythonのハッシュテーブル(辞書型)にも慣れてない感じがするんで、次のページを参考にしてください。

辞書型:
http://docs.python.jp/3/tutorial/datastructures. …

> 明らかに前提知識が不足していますがpython3の入門サイトが
> http://docs.python.jp/3/tutorial/controlflow.htm
> 以外見つからず悪戦苦闘してます。

では次のサイトを紹介しておきます。

Dive Into Python 3 日本語版:
http://diveintopython3-ja.rdy.jp
    • good
    • 1

冗談がお好きなようですねw



> Python入門サイトの説明不足で私は悪くありません。
> 私の理解力がないわけではありません。

> 例えば*a,*bと関数を定義した場合どのように*aと*bの判断するのでしょうか?

疑問に思われていらっしゃるとおり、判断できません。そのため、そのような定義は禁止されています。

これについては、問題の箇所の直後の「4.7.3. 任意引数リスト」に、

> 通常このような 可変 引数は、関数に渡される入力引数の残りを全て掬い取るために、仮引数リストの最後に置かれます。
> *args 引数の後にある仮引数は ‘キーワード専用’ 引数で、位置指定引数ではなくキーワード引数としてのみ使えます。

と明記されています。
    • good
    • 0

ちょっと聞いてみよう.



「最初のループではkeywords["Michael Palin"]ってことですよね」のところは, 何をどう考えた結果としてそのような結論になったんでしょうか?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!