hatunina’s blog

メモと日記です

Python2.7とPython3.5の組み込み関数lowerの話

たぶん超絶ニッチ
でも気になったから覚えているうちにまとめます。
なんならちゃんと解決してないので誰か教えてください。

状況

lower関数ですが、対象となる文字列を小文字に変換してくれるやつです。
まずはPython2.7での挙動を確認します。

# ABは半角
moji = 'AB'
print moji
print moji.lower()
# AB
# ab

# Bは全角
moji2 = 'AB'
print moji2
print moji2.lower()
# AB
# aB


対象文字が半角の際は小文字にしてくれますが、全角があると全角部分は何もしてくれません。

次はPython3.5の挙動です。

# ABは半角
moji = 'AB'
print(moji)
print(moji.lower())
# AB
# ab

# Bは全角
moji2='AB'
print(moji2)
print(moji2.lower())
# AB
# ab <- b は全角


半角全角関係なく小文字にしてくれます。ただ全角部分は全角のママです。
うーーむ、微妙な違いだけど困るぞい

原因

たぶん文字列型が原因です。(たぶんっていうのはlowerの中身のコードをまだ確認できていないから)
それぞれprintを用いずに出力してみます。

# 2.7
moji
# 'AB'
moji2
# 'A\xef\xbc\xa2'

# 3.5
moji
# 'AB'
moji2
# 'AB'


bytes型とunicode型の違いですね。
2系はASCIIを元にしたbytes型がデフォルトなので全角はUTF-8で符号化されるっぽい?です。
3系はunicode型がデフォルトなので全角も関係なく1文字で表現できています。

で、おそらくlowerはfor文か何かで1文字ずつ対象文字列を取り出して小文字に変換してんじゃないっすか?
全角Bの部分は\xef\xbc\xa2なので\xef, \xbc, \xa2という感じで取り出されちゃって、わけわかんねえぜ!ってなっているんじゃないかと

はい、かいけつ〜、てきと〜

まとめ

また時間のある時にソースコード見て確認します。
あと、2.7から3.5に移行してて、思ってたより簡単〜みたいなことをつい最近書いた気がするけど、やっぱ大変っすね、さーせん