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

このQ&Aに関連する最新のQ&A

A 回答 (3件)

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



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

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

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

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

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

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

ええと、まずは。



> **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

ちょっと聞いてみよう.



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

このQ&Aに関連する人気のQ&A

このQ&Aと関連する良く見られている質問

QInvalid procedure call or argument エラー発生時の対応

Run-time error '5':
Invalid procedure call or argument

作成中のエクセルマクロ(xls)で、上記エラーが発生しました。
日本語版PCでは問題ないのですが、英語版PCでは上記エラーが出ております。

日本でも海外でも両方で使えるように仕組みを改修したいのですが、何かいい方法はありませんでしょうか。

インターネットで検索したところ、「現地の言語設定を日本語に変更すればよい」という記述を数件確認したのですが、現地の言語設定は変更せずに現地のままでエラー解消できる方法を探っています。
(現地いわく、何故このマクロの為に言語設定を日本語に変えないのいけないのかと・・まぁそれもそうかと)

どんな内容のご回答でも結構です。何かヒントになることでも結構ですので、アドバイスください。
困っています。。

Aベストアンサー

>「現地の言語設定を日本語に変更すればよい」
VBAにとっては、日本語は、単にユーザーフレンドリーという役割でしかないと思います。私の持っているVBAエラー表は英語です。

日本語に変える必要はまったくないと思います。ただし、日本語/2バイト文字を扱うならば、ちょっと事情が違ってきますが。

Invalid procedure call or argument
プロシージャの呼び出し、または引数が不正です。

と読めませんか?そして、引数に数値を入れるところなのに、文字列(2バイト文字)が入ってしまった場合などに発生します。さしずめ、全角空白ということろでしょうか。

QUnityのエラー「Rigidbody.AddForce(0,0,speed);」

UnityでJavaを書いています。
実行すると

Rigidbody.AddForce(0,0,speed);

上記の箇所にエラーがあると言われたのですが、
どこが問題なのかわかりません。

お分かりの方がいたら、ご教授ください。
その前後のコードも記載します。


//上矢印キーが押された場合
if(Input.GetKeyDown(KeyCode.UpArrow)){
//玉のZ軸に対して正の力を加える
Rigidbody.AddForce(0,0,speed);
}

//下矢印キーが押された場合
if(Input.GetKeyDown(KeyCode.DownArrow)){
//玉のZ軸に対して負の力を加える
Rigidbody.AddForce(0,0,-speed);
}

Aベストアンサー

Javaは凄くうっすらやった事がある程度なのですが、
こちらのサイトを参考にすると「Rigidbody.AddForce(」の後は
数字ではなく英語にて指示を記述しているので、そこを変えてみたら直るかも…?

http://openbook4.me/projects/161/sections/1045

Qobjective-cでの、「*」の意味

タイトルのままですが、objective-cでの、
「*」の意味を教えて下さい!
どなたかよろしくお願い致します。

Aベストアンサー

掛け算とかポインタとか。
とりあえず、入門書を読むところから始めてはどうでしょうか?

QACCESS VBAでテーブル内の特定のフィールドを削除 .Fields.Delete ("*")

教えて下さい。
 倉庫テーブル
  フィールド:
   北海道倉庫1
   北海道倉庫2
   仙台倉庫1
   仙台倉庫2
   仙台倉庫3



とあります。仙台と付くフィールドを全て削除したく

CurrentDb().TableDefs("倉庫テーブル").Fields.Delete ("仙台倉庫1")

の”仙台倉庫1”の部分を
(”仙台”&”*”)にしたのですが、動きません。
どのように書けば良いのでしょうか?
宜しくお願い致します。

Aベストアンサー

さすがにそのワイルドカードは無理。
こんな風では?

Sub てすと()
Dim DB As Database
Dim Tdf As DAO.TableDef
Dim Fld As DAO.Field
Dim i As Integer
Set DB = Application.CurrentDb
Set Tdf = DB.TableDefs("倉庫テーブル")

For i = Tdf.Fields.Count - 1 To 0 Step -1
If Tdf.Fields(i).Name Like "仙台*" Then
Debug.Print Tdf.Fields(i).Name
'Tdf.Fields.Delete Tdf.Fields(i).Name
End If
Next
Set Tdf = Nothing: Set DB = Nothing
End Sub

確認のためイミディエイトウィンドウに出力してますので
OKだったら下のコメントを外して実行してください。
※念のためバックアップを取ってからに。

QVBA ThisWorkbookはSheet*で記述されたものより優先される?

よろしくお願いします。

VBEでSheetやThisWorkbookにコード記述する場合がありますが、
ThisWorkbook側に記述したものは全シートで同じ処理が実行されるのは知っていますが
例えばSheet2だけThisWorkbookの指示(処理)を行わせたくない・・場合、
どのようなコードを記述すればよいか、ご教授をお願いいたします。


非常に簡単なものだと列幅を統一したい場合
Range("a:zz").ColumnWidth = 2.88
などと記述すればどのシートでも列幅2.88に統一されますが、逆にSheet2だけは
列幅8にしたい、オート幅にしたいと言う場合、コードをSheet側に記述しても
ThisWorkbook側に記述したコードが優先されてしまいます。

ThisWorkbook側でSheet2を除外する、というIf文なりを書いて例外処理させても
いいのですが、これだとシート数が増える度にコード変更しなければならず
メンテナンス性が落ちます。
できればSheet側の記述を優先させればいいようにしたいのです。
まあSheet数を数えてRedimで再構築後にSheet2、7は適用外にせよと
書いてもいいのでしょうが、個人的にその方法はしっくりこないもので。

以上、宜しくお願い申し上げます。

よろしくお願いします。

VBEでSheetやThisWorkbookにコード記述する場合がありますが、
ThisWorkbook側に記述したものは全シートで同じ処理が実行されるのは知っていますが
例えばSheet2だけThisWorkbookの指示(処理)を行わせたくない・・場合、
どのようなコードを記述すればよいか、ご教授をお願いいたします。


非常に簡単なものだと列幅を統一したい場合
Range("a:zz").ColumnWidth = 2.88
などと記述すればどのシートでも列幅2.88に統一されますが、逆にSheet2だけは
列幅8にしたい、オート...続きを読む

Aベストアンサー

ThisWorkbook側に記述したコードが優先されるわけではなくて、最初にWorkSheet側のイベントプロシジャが実行され、次のWorkbook側のイベントプロシジャが実行されるということです。結果的に後から実行されたWorkbook側の列幅が適用されることになります。

そこで、こんな書き方はいかがでしょう。

【Sheet1オブジェクト】
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
MsgBox "Worksheet_BeforeDoubleClick"
処理済みSheetBeforeDoubleClick = True
End Sub

【ThisWorkbookオブジェクト】
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
If 処理済みSheetBeforeDoubleClick = False Then
MsgBox "Workbook_SheetBeforeDoubleClick"
End If
処理済みSheetBeforeDoubleClick = False
End Sub

【標準モジュール】
Public 処理済みSheetBeforeDoubleClick As Boolean

ThisWorkbook側に記述したコードが優先されるわけではなくて、最初にWorkSheet側のイベントプロシジャが実行され、次のWorkbook側のイベントプロシジャが実行されるということです。結果的に後から実行されたWorkbook側の列幅が適用されることになります。

そこで、こんな書き方はいかがでしょう。

【Sheet1オブジェクト】
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
MsgBox "Worksheet_BeforeDoubleClick"
処理済みSheetBeforeDoubleClick = True
End Sub

...続きを読む

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


人気Q&Aランキング

おすすめ情報