文字列編

p.83-109 文字列

最初の表だけであらかた事足りてる気もする。

「'''」で囲むとブロック文字列。「'」だと改行不可。
>>> hoge = '''hoge
... hoge
... hoge
... '''
>>> hoge
'hoge\nhoge\nhoge\n'
>>> hoge = 'hoge
  File "<stdin>", line 1
    hoge = 'hoge
               ^
SyntaxError: EOL while scanning string literal

で、これを利用してよくコメントを書いたりするわけですね。よく見る。

スライシング便利だけど、ちょっと直感に反する
>>> hoge[2:10]
'ge\nhoge\n'

2文字目から10文字ではなくて、2文字目から10文字目の前までなのが罠。

ケツから2文字なら下記。考えたらわかるけど。

>>> hoge[-2:]

ここは何度も間違いそう。

なんで hoge.length じゃなくて len(hoge) なんだろう。

多分あちこちで言われてると思うので、一応あとで調べる。

エスケープシーケンスについて

「/」に続く文字がエスケープシーケンスではない場合文字列扱いになるが、明示的に「//」を使うべき。
或いは raw 文字列を使う。

r'C:\hoge\hoge'

※raw 文字列は正規表現書く時にきっと使うので覚えておく!!

p.90 この辺からムズい Unicode 文字列の話と思いきや、詳しく書いてくれてない・・・

encode, decode 周りはネズミ本使わずに要復習。

i18n の意味。今まで3回くらい何だっけ?ってなって都度ググってる気がする。今回もきっと忘れるけど、↓ってことですよ、と。
>>> i18n = 'internationalization'
>>> len(i18n[1:len(i18n)-1])
18
文字列についても in とか for とか使えるので注意が必要。スライシングできること考えれば道理。

'h' in "hoge" とか
[v for v in "hoge"] とかできるので注意が必要と。

オブジェクトのコピーは [:] で行う。

これは結構重要そう。

>>> l = [1,2]
>>> l.append(l)
>>> l
[1, 2, [...]]
>>> m = l
>>> n = l[:]
>>> l[1] = 100
>>> m
[1, 100, [...]]
>>> n
[1, 2, [1, 100, [...]]]

はいはいはい、わかるわかる。

p.96 スライシングには3つ目のインデックスが指定可能。

せっかくなので、今まででできたのを利用して fizzbuzz 問題を解いてみた。

>>> n = range(0,100)
>>> ['fizzbuzz' if v in n[0:len(n):3*5] else 'fizz' if v in n[0:len(n):3] else 'buzz' if v in n[0:len(n):5] else v for v in n]
['fizzbuzz', 1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz', 16, 17, 'fizz', 19, 'buzz', 'fizz', 22, 23, 'fizz', 'buzz', 26, 'fizz', 28, 29, 'fizzbuzz', 31, 32, 'fizz', 34, 'buzz', 'fizz', 37, 38, 'fizz', 'buzz', 41, 'fizz', 43, 44, 'fizzbuzz', 46, 47, 'fizz', 49, 'buzz', 'fizz', 52, 53, 'fizz', 'buzz', 56, 'fizz', 58, 59, 'fizzbuzz', 61, 62, 'fizz', 64, 'buzz', 'fizz', 67, 68, 'fizz', 'buzz', 71, 'fizz', 73, 74, 'fizzbuzz', 76, 77, 'fizz', 79, 'buzz', 'fizz', 82, 83, 'fizz', 'buzz', 86, 'fizz', 88, 89, 'fizzbuzz', 91, 92, 'fizz', 94, 'buzz', 'fizz', 97, 98, 'fizz']

こういうもっと何とかなりそう感がある場合は確実にもっと何とかなる。目標に「Python でスタイリッシュに fizzbuzz 解く」を追加する。

文字列オブジェクトは変更不可。変更するには新たにつくり直す必要があるので、文字列操作時はパフォーマンスに注意。
フォーマット(like sprintf) には dict を使用可能。これは知らんかった。
>>> 'say %(num)d times %(what)s' % {'test':'nothing', 'num':100, 'what': 'hello!'}
'say 100 times hello!'

超使いそう。

p.101 vars() はよく使うって書いてたけどほんとに使うんだろうか。
直感ではデバッグ意外に使いたくない。

てことで、サラッと読むつもりが案外大変でした。

乗り越えたい壁

思いつくものから羅列。

実は実戦投入は済んでるのが怖い。
も少し本格的な実戦投入も控えてるのでちょっと頑張る。
フレームワークとかはもっと先でいいや。

Python での list の merge

python で list をマージしたい時はどうしたらいいんだろう。
考えるよりまずググる Google 脳なので、「python list merge」でググッたところ、こんな記法が目を引いた。

>>>a = [1,2,3]
>>>b = [4,5,6]
>>>[x for sublist in [a,b] for x in sublist]
[1, 2, 3, 4, 5, 6]

気に入ったけど何のことかわからない。
重い腰を上げて考えます。

まずこの [x for sublist in [a,b]... 最初の x が意味わからない。

分解してみる。

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> [x for sublist in [a,b]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

そりゃそうだ。これは何となくわかる。

>>> [sublist for sublist in [a,b]]
[[1, 2, 3], [4, 5, 6]]

OK、何となくわかった。
結果を想像しながら次。

>>> [a for sublist in [a,b]]
[[1, 2, 3], [1, 2, 3]]

[] の先頭に最終的に list に代入させたいものを書けばよさげ。

>>> [sublist.pop(0) for sublist in [a,b]]
[1, 4]

超便利!!


で、2個目の for の意味もよくわからない。
なんか何個でも for 書いていいみたいだけど。

(例)

>>> [x for sublist in [a,b] for hoge in sublist for x in [hoge]]
[1, 2, 3, 4, 5, 6]

for 文以外書いたら怒られた。
ネズ本読んでたらその内教えてくれるだろうか。

普通に書くならこっちな気がする

もうちょっとググったらもっとわかりやすそうなの出てきた。

>>> from heapq import merge
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> list(merge(a,b))
[1, 2, 3, 4, 5, 6]

こういう時ってどうすればいいんだろう。
php 書く時なら迷わず下を選択するんだけど。

追記

コメント欄で教えていただきました。id:podhmo さん、ひげさんありがとうございます。

>>>a.extend(b)
[1, 2, 3, 4, 5, 6]
>>>a.append(b)
[1, 2, 3, [4, 5, 6]]

とてもわかりやすいので、今後僕は extend を使います。
見よう見まねで書いたコードで append すべきところで extend 使ってて、
その後 join してたから extend の挙動を完全に間違って覚えてました。


あと、+ でもいいみたいだけど、extend 使う方が意図が明確だし、
これは使わないかもしれない。

>>>a+b
[1, 2, 3, 4, 5, 6]

Python ちゃんとやります。


初めての Python を借りて1ヶ月。
丸めて押入れに押しこんでおいたラグが春夏の間にすっかり型が付いちゃって、ほっとくとくるくる巻き上がる。仕方なく程よい重さのあるこの本に端っこを押さえる役目を与えてきたんだけど、そろそろ平らになってきたのでその任を解こうと思う。

ごめんなさい、これから読みます。

因みにラグの反対側の端っこは、別の方から2年前に借りた DVD を観ずに返そうとしたら返し返されたやつが押さえてます。
うそです、これから観ます。

あと、この本表紙がネズミなんだけど「初めてのチュー」ってことだろうか。
うそです、翻訳本です。

Pythonスクレイピングとかテスト用の画像作成ツールとか便利ツール作るときに見よう見まねで書いてたんだけど、ここらで一から再入門します。

早速 p.80 くらいまで読んだ。

import と from の違い

p.41

import moduleName
print moduleName.attribueName

↑と↓は同意

from moduleName import attributeName
print attributeName

今までコードコピペしてたらどっちもあったし、datetime.datetime() とか気持ちわりいと思ってたけど納得。

変数は全部オブジェクトへの参照

p.55 の演習で、「以下のコードを入力してみてください。」ってあったのでやってみた。

L = [1,2]
L.append(L)
L

無限ループで落ちるかと思いきや、

>>> L=[1,2]
>>> L.append(L)
>>> L
[1, 2, [...]]

何これキモい。[...]何?と思って中身見ようとしたら、

>>> L[2]
[1, 2, [...]]
>>> L[2][2]
[1, 2, [...]]
>>> L[2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2]
[1, 2, [...]]

キ・モ・い!しかも速い。
なんでこんなこと出来るかっていったら、Python では変数は全部値のオブジェクトへの参照だからなんじゃないですかね。

L[2] が L を参照してるだけってこと?

試しに値を変更してみる。

>>> L[1]=3
>>> L
[1, 3, [...]]
>>> L[2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2]
[1, 3, [...]]

L[2]は L を参照してるので、L[2][2] も L[2]..[2] も同じ内容になる。