今日のPython
breakとcontinue
p.84
>>> for item in range(10): ... if item == 5: continue ... if item == 8: break ... print item, ... 0 1 2 3 4 6 7
while文
whileの条件はbool型(真or偽)で判定される。
p.86
>>> n = 0 >>> while n < 10: ... print n, ... n += 1 ... 0 1 2 3 4 5 6 7 8 9
九九の表を出力
よくやるよね。
>>> a = 1 >>> b = 1 >>> while a < 10: ... while b < 10: ... print a * b, ... b += 1 ... print "" ... a += 1 ... 1 2 3 4 5 6 7 8 9
あれ、できない><
この改行は一体・・・
あ、わかった
>>> a = 1 >>> b = 1 >>> while a < 10: ... while b < 10: ... print a * b, ... b += 1 ... print "" ... a += 1 ... b = 1 #これ忘れてた ... 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
for文と違うから、段が変わったら(aをインクリメントしたら)bの値をセットし直さないといけないんだった。初歩ミスすぎる><
表示桁数の調整がわからないからズレまくりだ
for文で書くとこう
>>> for a in range(1, 10): ... for b in range(1, 10): ... print a * b, ... print "" ... 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
こっちの方がエレガントですね!
do〜while文がないので
Cのdo〜while文を使って0〜9を表示するとこんな感じ。
int main(void) { int n = 0; do { printf("%d ", n++); } while (n < 10); printf("\n"); return 0; }
Pythonではdo〜while文がないので、while文(無限ループ)とbreakを組み合わせて書く。
p.87
>>> n = 0 >>> while True: #無限ループ ... print n, ... n += 1 ... if n == 10: ... break ... 0 1 2 3 4 5 6 7 8 9
関数
関数を作る
p.92 文字列を表示する関数を定義する
>>> def oppy(): ... print"Oppy(oppai)!!" ... >>> oppy() Oppy(oppai)!!
def 関数名(引数):
[tab] 処理内容
て感じ。
引数の型を指定できないことに注意!
p.93
# 引数の回数だけ文字列を表示する >>> def greeting(hello, python): ... print "Hello " * hello, ... print "Python!! " * python, ... >>> greeting(3,2) Hello Hello Hello Python!! Python!!
# 引数で与えた文字列を指定した回数表示する >>> def functest(str, int): ... print str * int ... >>> functest("こんにちは! ", 5) こんにちは! こんにちは! こんにちは! こんにちは! こんにちは!
こんな風に同時に受け取る引数の型が違う場合、関数の定義を読んだだけじゃ型がわからないけど、こんがらがったりしないの?
引数のデフォルト値
呼び出すとき、特に引数の指定がなかった場合に用いられる値。
p.95
>>> def greet(str="Hello, Python!! ", int=3): #引数にデフォルト値を代入 ... print str * int ... >>> greet() #引数を指定しない Hello, Python!! Hello, Python!! Hello, Python!! >>> greet("Goodbye!! ", 2) #引数を指定 Goodbye!! Goodbye!!
ローカル変数と戻り値
関数内で定義された変数はローカル変数となる。ローカル変数は関数の外では使えない。
一般的な名前空間と同じかな。
p.96 戻り値を使ってみる
>>> def power(a=2, b=3): ... pow = a ** b ... return pow ... >>> a = power() >>> a 8
returnで戻り値。これ使うメリットがまだない・・・
p.98 ローカル変数の実験
>>> def foo(num): ... a = 1 #関数内で定義 ... print a, num ... >>> foo(100) 1 100 >>> print a #関数外で呼び出し Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined
ファイル処理
ファイルの読み込み
以下のファイル内容のfoo.txtを使う
aiueo
bbb
ccc
p.103 ファイルを読み込んでみる
>>> f = open("foo.txt", "r") >>> s = f.read() >>> s 'aiueo\nbbb\nccc\n' >>> f.close()
open(),close()でファイルを開く/閉じる。読み込む場合はread()を使う
ファイルオブジェクトの読み込みメソッド
p.105
- F.read(整数のサイズ)
- ファイルから読み込みを行い、ファイルの終わりまでをひとつの文字列として返す。引数が指定されている場合、シーク位置からサイズ(バイト)分だけ読み込みを行う。
- F.readline(整数のサイズ)
- ファイルから1行読み込み、文字列として返す。引数を指定すると、読み込む行頭からの最大バイト数を指定できる。
- F.readlines(整数のサイズ)
- 複数行を一度に読み込む。文字列を要素としたリストを返す。引数がない場合はファイルの最後までを読み込み、行に分割したリストを返す。引数を指定すると、行頭からの最大バイト数を指定できる。
F.read()の動作例とシーク位置の考察
>>> f = open("foo.txt", "r") >>> s = f.read(5) #先頭から5バイト >>> s 'aiueo' >>> t = f.read(5) #次の5バイト >>> t '\nbbb\n' >>> u = f.read() #残り >>> u 'ccc\n'
シーク位置(読み出し開始位置)の動きがわかりますね。
F.readline()の動作例
>>> f = open("foo.txt", "r") >>> s = f.readline() >>> s 'aiueo\n' >>> f = open("foo.txt", "r") >>> t = f.readline(2) #2バイトまで読み込む >>> t 'ai'
F.readlines()の動作例
>>> f = open("foo.txt", "r") >>> s = f.readlines() >>> s ['aiueo\n', 'bbb\n', 'ccc\n'] >>> f = open("foo.txt", "r") >>> s = f.readlines(2) #2バイトまで読み込む >>> s ['aiueo\n', 'bbb\n', 'ccc\n'] #全然2バイトじゃないよ!
ちょっと、引数指定しても何ともないよ!
for文で1行ずつ読み込む
p.106
>>> f = open("foo.txt", "r") >>> for line in f.readlines(): ... print line, ... aiueo bbb ccc
f.readlines() == ['aiueo\n', 'bbb\n', 'ccc\n']
というシーケンスだから1行ずつ表示できるわけですね、わかります。
もっと簡潔に書けます。
p.107
>>> f = open("foo.txt") >>> for line in f: ... print line, ... aiueo bbb ccc
ファイルを書き込む
p.107
ファイルオブジェクトの書き込みメソッド
- F.write(文字列)
- 文字列を指定して、ファイルに対して書き出しを行う。戻り値なし
- F.writelines(シーケンス)
- 文字列を要素に含むシーケンスを引数に与え、ファイルを書き出す。書き出すとき、改行文字を付加しないので注意。
F.write()の動作例
>>> str = "ama-ch " >>> f = open("test.txt", "w") >>> f.write(str * 3) >>> f.close() >>> g = open("test.txt") #書き込み内容確認 >>> for look in g: ... print look ... ama-ch ama-ch ama-ch
F.writelines()の動作例
>>> f = open("foo.txt") #こっから読み込んで >>> g = open("test.txt", "w") #こっちへ書き込む。 >>> g.writelines(f.readlines()) #f.readlines() == ['aiueo\n', 'bbb\n', 'ccc\n'] >>> f.close() >>> g.close() >>> g = open("test.txt") #書き込み内容確認 >>> for look in g: ... print look, ... aiueo bbb ccc
書き込むとき、for文で1行ずつ読み込んだときと同じでf.readlines()をfで表せます。
慣れるまではfって書いちゃうとわかりにくそうだから素直にかいとこ。
失敗例
>>> f = open("foo.txt") >>> g = open("test.txt", "w") >>> g.writelines(f) >>> f.close() >>> for look in g: #gに書き込んだ後、close()する前に中身を確認しようとする ... print look, ... Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno 9] Bad file descriptor
エラーになる!書き込みモード(wオプション)で開いたファイルオブジェクトをそのまま覗こうとしたから?
これでどうだ
>>> f = open("foo.txt") >>> g = open("test.txt", "w+") #オプションを読み書きできるモードにする >>> g.writelines(f) >>> f.close() >>> for look in g: #読めるかな? ... print look, ... #読めなかった・・・ >>> g.readlines() #シーケンスg.readlines()を確認 [] #あれ、空っぽだ! >>> g.close() >>> g = open("test.txt") #読み込みモードで開き直し >>> for look in g: ... print look, ... aiueo #読めた bbb ccc
あ〜シーク位置のこと考えてなかった!これが原因か!
g.writelines(f)の時点で、f,gのシーク位置は最後になる。
この最後のシーク位置からg.readlines()しようとしてたんだから、そりゃ空っぽになるわけか! オプションrでopenし直すとシーク位置が先頭にくるから普通に読み込んで表示できると。
そろそろ疲れたのでおしまい。
微妙にみんPyと違う結果になるところがあるな・・・
今日は色々できて楽しかった。今日も20ページちょい進んだ 昨日より長くやったのに同じとな><