忍者ブログ
Yaleで、遊んで学ぶ日々。

Yaleで、遊んで学ぶ日々。

囲碁、ときどきプログラミング、ところにより経済。
[1]  [2]  [3]  [4
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

Pythonを使って、テキストをコンソール上に表示したり、ファイルに書き込んだりしていると、特に日本語を使っている時には、エンコードに起因するエラーが生じることがある。

'ascii' codec can't encode characters in position ...

というようなエラーメッセージだ。



深い部分はよく分からないが、対処方法は比較的シンプルだ。


 * Unicode に変換

日本語のテキストファイルは、文字コードに S-JIS が使われていることが多い。これは、Windowsのデフォルトだからだと思うが、Pythonで扱う場合はUnicodeであった方が紛れが少ない。そこで、まずはUnicodeにしてしまおう。

x = unicode(x, "sjis", "ignore")

"sjis"  の部分を "utf-8" とかにすれば、他の文字コードのテキストにも使える。"ignore" という引数は、確かちょっと変換が上手く行かないを無視するという意味合いだったと思うが、テキストの一部分に非常に珍しい文字が使われていたりすることによるエラーを避けることができる。


* 表示したり書き込んだりするときは、encode() 関数を噛ませるといい。

print x

with open("tmp.txt", 'w') as f:
    f.write(x)


としたときに上記のようなエラーが出る場合、encode() 関数を使って変換してやると上手くいくようだ。

print x.encode('utf-8')

with open("tmp.txt", 'w') as f:
    f.write(x.encode('utf-8'))


こうするとUnicode文字列がUTF8に変換される。僕の環境ではUTF8がいいようだが、変換するコードは自分の環境に合わせて選ぶ。
PR
Web scraping でHTMLソースをあれこれ解析していたら、文字が何やらコードで書かれている場所が見つかった。

0件です。

これで「0件です」と読むらしい。

仕組みはというと、 「&#」 と 「;」  で数字をサンドイッチしている形式で、数字の部分がUnicodeのコード番号になっている。

ちなみに、数字部分が16進数になっていることもある。同じ「0件です。」を16進数で書くには、

0件です。

とする。数字の前に「x」が付くのが16進数表示にするときの約束だ。



さて、これを「0件です。」に変換するには、unichr() 関数を利用する。unichr() 関数は、整数を引数に取り、対応する文字を返す。
たとえば、件 の部分なら、
txt = '件'
code = txt[2:-1]
uni = unichr(int(code))
とすると、「件」というUnicodeになる。

16進数の場合、int() 関数で整数に変換する時に16という引数を与える。
txt = '件'
code = txt[3:-1]
uni = unichr(int(code, 16))




例えば番号1からループでファイルを作ったとして、

1.png, 2.png, ...., 99.png

となってみると、名前順で並べると(環境にもよるが)、

1.png, 10.png, 11.png,...

というように、きちんと番号順にならずに少しばかりイラっとなることがある。

python では、zfill() 関数を使えばこの問題はすっきりする。zfill() 関数は、文字数を指定すると文字列の空き部分に0を挿入してくれるちょい便利関数だ。
---------------------
'5'.zfill(3)

(結果) '005'
---------------------


これを使って001.png, 002.png, ... というファイル名にすれば、並び替えた時にきちんと番号順になるという仕掛け。ちなみに、文字列関数なので数値でなくても可能。
---------------------
'ab'.zfill(3)

(結果) '0ab'
---------------------





datetimeパッケージのtimedelta() 関数で一発解決

----------------------------
import datetime
str(datetime.timedelta(seconds=500.25))

(結果)  '0:08:20.250000'
----------------------------




pythonで、
[ 'a', 'b', 'c' ]
のような文字列リストを
'abc'
というような1つの文字列にするには
------------------
x = ['a','b','c']
''.join(x)

(結果) 'abc'
------------------
つまり、空文字列でリスト x を結合する、ということ。


別の用法として、
------------------
x = [ '1st line', '2nd line', '3rd line' ]
'\n'.join(x)

(結果) '1st line\n2nd line\n3rd line'
------------------
のようにして、リストの各要素が改行でつながれたテキストを作ることが出来る。これは、ファイルへの書き込みの時の常用手段。要素についてループを回して writeline() を使うより、改行を含んだ1つの文字列を write() で書き込んだ方がプログラムがすっきりする。



join() の逆の働きをするのは split() 関数。例えば、
------------------
x = '1ban:2ban:3ban'
x.split(':')

(結果)
['1ban', '2ban', '3ban']
------------------


用法は様々。例えば単純なCSVファイルなら、ファイルをxに読み込んで、
------------------
x = x.split('\n')
x = x.split(',')
------------------
とすればCSVファイルを2次元配列で取りこめる(注. 厳密には要素内にコンマや改行が入っている場合等への対応が必要。CSV読み込みには csv パッケージを利用するのが良い)。



Calender
02 2024/03 04
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Search in This Blog
Latest Comments
[03/30 川内のばば山田]
[03/30 川内のばば山田]
[08/06 Aterarie]
[07/05 Agazoger]
[07/01 Thomaskina]
Oldest Posts
Latest Trackbacks
フリーエリア

Barcode
Access Analysis
Powerd by NINJAブログ / Designed by SUSH
Copyright © Yaleで、遊んで学ぶ日々。 All Rights Reserved.
忍者ブログ [PR]