今さらPython3 (22) - While
この本の第4章を読んでます。
- 作者: Bill Lubanovic,斎藤康毅,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/12/01
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Whileは難しい?
>>> while count <= 5: ... print(count) ... count += 1 ... 1 2 3 4 5 >>>
昔(てか今もか)、他の言語でWhile文を作る時になんとも面倒だなと思っていたのが、While文の条件のところ。while文自体に条件を付けたり、Pythonにはないけどendwhileのところにも条件を付けられたりと、便利ではあるけど少し怖いなと思いながら使っていたけど、pythonの場合はシンプルに書けそうなので幾分気持ちが楽。
とか言いながら、最後のcount+=1を忘れて無限ループさせちゃったりするんだけど(苦笑)
>>> while True: ... stuff = input("String to capitalize [type q to quit]: ") ... if stuff == 'q': ... break ... print(stuff.capitalize()) ... String to capitalize [type q to quit]: abc Abc String to capitalize [type q to quit]: bcd Bcd String to capitalize [type q to quit]: quize Quize String to capitalize [type q to quit]: q >>>
whileの中で条件を満たした場合にbreakするのが、この上の例ですと。実際には、文字を入れた後にEnterするので、quizeみたいなq始まりの単語でも大丈夫ですね。
continueの使い方
>>> while True: ... value = input("Integer, please [q to quit]:") ... if value == 'q': #quit ... break ... number = int(value) ... if number %2 == 0: #an even number ... continue ... print(number, "squared is", number*number) ... Integer, please [q to quit]:1 1 squared is 1 Integer, please [q to quit]:2 Integer, please [q to quit]:3 3 squared is 9 Integer, please [q to quit]:4 Integer, please [q to quit]:5 5 squared is 25 Integer, please [q to quit]:6 Integer, please [q to quit]:7 7 squared is 49 Integer, please [q to quit]:2.6 Traceback (most recent call last): File "<stdin>", line 5, in <module> ValueError: invalid literal for int() with base 10: '2.6' >>> int(2.6) 2 >>>
continueというのは、whileブロックの中にcontinue以下の処理を飛ばして次のループを処理するという理解でOKそう。1つ気になるのは、2.6というfloatを渡したときにエラーとなった辺りかな。インタプリタでint(2.6)を渡すと丸めてくれるのに、何で挙動が違うんだろうか?
ということで、インプットした値がどういう型(type)で渡されるかを出力する1行を追加して再トライ。
>>> while True: ... value = input("Integer, please [q to quit]:") ... if value == 'q': #quit ... break ... print(type(value)) ... number = int(value) ... if number %2 == 0: #an even number ... continue ... print(number, "squared is", number*number) ... Integer, please [q to quit]:1 <class 'str'> 1 squared is 1 Integer, please [q to quit]:2 <class 'str'> Integer, please [q to quit]:3 <class 'str'> 3 squared is 9 Integer, please [q to quit]:4 <class 'str'> Integer, please [q to quit]:5 <class 'str'> 5 squared is 25 Integer, please [q to quit]:2.6 <class 'str'> Traceback (most recent call last): File "<stdin>", line 6, in <module> ValueError: invalid literal for int() with base 10: '2.6' >>>
これを見ると、input文で入力した場合は、いったんstrとして格納される訳ですね。
>>> int(str('2.6')) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: '2.6' >>> int(str('2')) 2 >>>
文字型の'2.6'を直接intには変換できないと。動作としては理解。
while...else
これは意識して使ったことがないパターンかも。
>>> numbers = [1, 3, 5] >>> position = 0 >>> while position < len(numbers): ... number = numbers[position] ... if number % 2 == 0: ... print('Found even number', number) ... break ... position += 1 ... else: #break not called ... print("No even number found") ... No even number found
breakが呼び出されなかった場合は、elseのブロックが処理されるということね。
>>> numbers = [1, 2, 3, 6] >>> while position < len(numbers): ... number = numbers[position] ... if number % 2 == 0: ... print('Found even number', number) ... break ... position += 1 ... else: #break not called ... print("No even number found") ... No even number found >>> numbers [1, 2, 3, 6] >>> position 4 >>> position = 0 >>> while position < len(numbers): ... number = numbers[position] ... if number % 2 == 0: ... print('Found even number', number) ... break ... position += 1 ... else: #break not called ... print("No even number found") ... Found even number 2 >>>
じゃ、偶数がある場合にどうなるの?と思って試したら結果が変だと思った時の履歴。単純にpositionの初期化を忘れていて、処理した時点でpositionが4になっていたので直接elseブロックに飛んでいた事が判明。
(つづく)