5/05/2011

[読書] Python クックブック 第2版 読んでみる。第1章-その1

内容は2.x系向けに書かれてる。3.x系ではどうするの?と考えながら読んでみるなどする。
いつも通り、間違ってても、車輪の再発明になっても気にしない。娯楽なので。
作戦:ガンガンいこうぜ。




1.3 オブジェクトが文字列のようなものかテストする

Python2では文字列の方が、Unicode型と非Unicode型があり、スーパクラスとしてbasestring型があった。
これをisinstance()に渡すと、Unicodeか否かの判別ができた。
basestringデータ型 はPython3にはないので、素直にisinstance(anobj,str)でよい。


1.6 文字列の連結

Pythonの文字列はイミュータブル。Javaで文字列を+連結するのと同じ問題を孕む。
''.joinを使うのが正解だよね。



1.8 文字列にキャラクタセットの文字が含まれるか調べる

itertools.ifilter() はPython 3では 標準ビルトイン関数 filter() になっている

書き変えてみる
def containsAny2(seq, aset):
  for item in filter(aset.__contains__,seq):
  return True
 return False

not の結果がemptyだとTrueが戻ることを利用。
def containsAll(seq,aset):
 return not set(aset).difference(seq)


>>> not set()
True
>>> not set('a')
False


>>> not ''
True
>>> not 'a'
False

Python 3 では Python 2 の string.maketrans とそっくりのスタティックメソッド maketrans がバイト列型に加わっている。
そしてユニコード文字列型にも maketrans スタティックメソッドが追加された。
これはユニコード文字列型の translate に渡せる辞書を返す。

調査対象文字列に、任意の文字列を1つでも含むか?
def containsAny(astr,strset):
 notrans = str.maketrans('','',astr)
 return len(strset) != len(strset.translate(notrans))


1.9 文字列クラスのtranslateメソッドを簡単に使う。

クロージャーを使ったラッパを作っているが、3.xではサンプルは動かない。
練習がてらユニコード文字列の maketransメソッドを使ったコードを書いてみた。

削除とkeepを2者択一にしてたりして機能縮小版。とりあえず。

def translator(frm='',to='',delete='',keep=None):
 if len(to) == 1:
  to = to * len(frm)
 if keep is not None:
  trans = str.maketrans('','',keep)
 else:
  trans = str.maketrans(frm,to,delete)
  
 def translate(s):
  if keep is not None:
   return s.translate(str.maketrans('','',s.translate(trans)))
  else:
   return s.translate(trans)
 return translate

a,dをbに変換して、数字だけ削除
>>> import string
>>> test = translator(frm='ad',to='b',delete=string.digits)
>>> test('aaaaaccccdddd123456789')
'bbbbbccccbbbb'

数字だけ残す
>>> test = translator(frm='ad',to='b',keep=string.digits)
>>> test('aaaaaccccdddd123456789')
'123456789'
>>>

ダブルバイト。愛は嘘なり。
>>> test = translator(frm='愛',to='嘘',delete=string.digits)
>>> test('愛愛愛123456789')
'嘘嘘嘘'
>>>

0 件のコメント: