"=" ではなく ":=" を使う。
ただし代入できるのは条件式に限られ、変数は一つのみであり、代入できるのも条件式全体に限られる。
通常の式の途中では代入出来ない。
あと、Python2 だと無理っぽい。
ただし代入できるのは条件式に限られ、変数は一つのみであり、代入できるのも条件式全体に限られる。
通常の式の途中では代入出来ない。
あと、Python2 だと無理っぽい。
他の言語のノリで以下のようなコードを書いたところ
状況的に見て Python では if の条件式に代入を書けないって事のようで、
C 畑の言語にどっぷり漬かり切った頭には、ある意味カルチャーショックと言うか、
いやいや、待ってください。if, else if, ... で条件に正規表現使いたい場合、条件式で代入書けないのは地味に辛くないですか?的な疑問が。
Python ってそんな不便な言語なの?
gawk の match(s, r [, a]) みたいに、マッチ結果を配列 a に返すみたいな仕組みがあれば良さそうな気がするが、
#!/usr/bin/env python3 import urllib.request import re url = 'https://pypi.org/simple/' with urllib.request.urlopen(url) as response: html = response.read().decode('utf-8') if m = re.search(r'(?s)<body>(.*)</body>', html): print(m.group(1))以下のようなエラーになった
$ ./hoge.py File "./hoge.py", line 8 if m = re.search(r'(?s)<body>(.*)</body>', html): ^ SyntaxError: invalid syntaxVisual Studio Code でも = と r の間のスペースに下線が表示されて、
Invalid Syntax (<unknown>, line 8) pylint(syntax-error) Peek Problem (Alt+F8) Noquick fixes availableみたいに言われてて、しばらく「は?」ってなった。
状況的に見て Python では if の条件式に代入を書けないって事のようで、
m = re.search(r'(?s)<body>(.*)</body>', html) if m: print(m.group(1))みたいに分けて書けってことのようである。
C 畑の言語にどっぷり漬かり切った頭には、ある意味カルチャーショックと言うか、
#include<stdio.h> #include<stdlib.h> int main() { for (int i = 0;; i++) { int fizz = i % 3; int buzz = i % 5; if (fizz = 0) printf("fizz"); if (buzz = 0) printf("buzz"); if (fizz && buzz) printf("%d", i); printf("\n"); } return EXIT_SUCCESS; }みたいに、未だについやってしまいがちな間抜けなバグを防げるのでフールプループ的な意味では悪くない仕様ですよねと、それはそれで納得はしたので、Python ってそういう仕様なんだーと、そこで終わりかかったのだが、
いやいや、待ってください。if, else if, ... で条件に正規表現使いたい場合、条件式で代入書けないのは地味に辛くないですか?的な疑問が。
Python ってそんな不便な言語なの?
gawk の match(s, r [, a]) みたいに、マッチ結果を配列 a に返すみたいな仕組みがあれば良さそうな気がするが、
- Python 標準ライブラリ / テキスト処理サービス / re --- 正規表現操作 # モジュールコンテンツ # re.search(pattern, string, flag=0)
これ、割と他の言語では出来る書き方なので、公式文書のどこかに注記がありそうに思うのだが、それらしいところが見つからない。
とりあえず、
こちらにも特に注記等はないし、
で、 を見ると、ようやく求めていた答えが。
まず、
次に、"=" による代入は
ただ、先程の演算子に := とか言う見慣れない演算子があって、これって Pascal の代入っぽくね?みたいな気がしたので試しに REPL に
何だこれ?って感じだけど、これは
で、ここに、
つまり、通常の代入文は "=" で代入するけど、
条件式の中で代入する場合は ":=" を使えということらしい。
残る問題は、代入式は if 文に与えられる式なのに、なんで先程書いた
ここに書けるのは、
一方、if 文に与えられる条件式は
つまり代入式は、まさに最初の疑問として挙げた「代入できないと if, elseif, ... で正規表現使いたい時に困るんじゃね?」に対する、答えのような機能と言っても良さそうだ。
あくまでも条件分岐の処理内で条件式の結果を使いたい場合の解決策的な機能であって、Python としては通常の式の中では代入なんてする必要はないだろって見解なんだろう。
とりあえず、
- re # マッチオブジェクト
match = re.search(pattern, string) if match: process(match)みたいに分けて書いてあるし、
- Python チュートリアル / 3. 形式ばらない Python の紹介 # 3.1. Python を電卓として使う # 3.1.1. 数
等号 (=) は変数に値を代入するときに使います。代入を行っても、結果は出力されず、次の入力プロンプトが表示されます。:みたいな記述があり、対話モードで演算は結果が表示され、代入は結果が表示されない例が示されているものの、
こちらにも特に注記等はないし、
- Python チュートリアル / 4. その他の制御フローツール # 4.1. if 文
で、 を見ると、ようやく求めていた答えが。
まず、
- Python 言語リファレンス / 2. 字句解析 # 2.5. 演算子
- Python 言語リファレンス / 2. 字句解析 # 2.6. デリミタ (delimiter)
次に、"=" による代入は
- Python 言語リファレンス / 7. 単純文 (simple statement) # 7.2. 代入文 (assignment statement)
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)みたいな BNF で定義されていて、例えば
a = b = 1みたいな一括代入は、前半の (target_list "=")+ の1回以上の繰り返しで実現されているので、右辺の starred_expression や yield_expression には含まれていないのであった。
ただ、先程の演算子に := とか言う見慣れない演算子があって、これって Pascal の代入っぽくね?みたいな気がしたので試しに REPL に
a := 1とか入れてみたら、
>>> a := 1 File "<stdin>", line 1 a := 1 ^ SyntaxError: invalid syntaxのようなエラーになった。
何だこれ?って感じだけど、これは
- Python 言語リファレンス / 6. 式 (expression) # 6.12. 代入式
assignment_expression ::= [identifier ":="] expressionと定義されてるらしい。
で、ここに、
if matching := pattern.search(data): do_something(matching)
while chunk := file.read(9000): process(chunk)みたいな例文が紹介されていた。
つまり、通常の代入文は "=" で代入するけど、
条件式の中で代入する場合は ":=" を使えということらしい。
残る問題は、代入式は if 文に与えられる式なのに、なんで先程書いた
a := 1みたいな式はエラーになんの?って話なんだが、
ここに書けるのは、
- Python 言語リファレンス / 7. 単純文 (simple statement) # 7.1. 式文 (expression statement)
expression_stmt ::= starred_expressionであり、これは
- Python 言語リファレンス / 6. 式 (expression) # 6.15. 式のリスト
starred_expression ::= expression | (starred_item ",")* [starred_item]である。
一方、if 文に与えられる条件式は
- Python 言語リファレンス / 8. 複合文 (compound statement) # 8.1. if 文
if_stmt ::= "if" assignment_expression ":" suite ("elif" assignment_expression ":" suite)* ["else" ":" suite]なのである。
つまり代入式は、まさに最初の疑問として挙げた「代入できないと if, elseif, ... で正規表現使いたい時に困るんじゃね?」に対する、答えのような機能と言っても良さそうだ。
あくまでも条件分岐の処理内で条件式の結果を使いたい場合の解決策的な機能であって、Python としては通常の式の中では代入なんてする必要はないだろって見解なんだろう。
タグ
コメントをかく