投稿者「admin」のアーカイブ

文字→ascii。ascii→文字 ord, chr

ord: アスキーコードを取得

>>> ord("a")
97

ユニコードオブジェクトの場合は、ユニコードを整数で返す。(python2)

>>> ord(u"あ")
12354
>>> hex(ord(u"あ"))
0x3042
>>> u"\u3042" == u"あ"
True

python3の場合は、文字列がはじめからユニコード文字列なので、uを付けなくてもよい。

>>> ord("あ")
12354

chr: アスキーコードから文字へ

>>> chr(97)
'a'

ユニコードはunichr(python2)

>>> unichr(12354)
u"\u3042" 

python3でははじめから文字列がユニコードなのでunichr関数は存在せずに、chr関数で文字コードから文字を得られる。(出力結果はpython2と違うが同値)

>>> chr(12354)
"あ" 

文字列の分割・結合 split, join,rsplit

split: 文字列の分割

str.split(sep)
sepを区切り文字として、単語を分割してリストにする。
区切り文字が指定されない場合は、スペース、タブ、改行文字列で分割される特殊なルールになる。

>>> "hello,world,foo,bar".split(",")
['hello', 'world', 'foo', 'bar']
>>> "hello,world, foo, bar".split(", ")
>>> "hello world\tfoo\nbar".split()
['hello', 'world', 'foo', 'bar']

第2引数で区切り文字で分割する回数を指定することができる。

>>> "aaa,bbb,ccc".split(",", 1)  #分割回数は1回に制限。('bbb,ccc'は分割されていない)
['aaa', 'bbb,ccc']

正規表現でのsplitの場合は、reモジュールを使用する。※ 正規表現split参照

>>> import re
>>> re.split(r'[,:]', "a,b:c")
['a', 'b', 'c']

join: 文字列シーケンスの連結

sep.join(seq)
sepを区切り文字として、seqを連結してひとつの文字列にする。

>>> ":".join(["a", "b", "cde"]);
'a:b:cde'

シーケンス.joinではなく、区切り文字列.join(シーケンス)なので注意。

rsplit: 右から文字列の分割

rsplitは右側から文字列を指定回数分割する。

>>> "/path/to/foo/bar/hoge.txt".rsplit("/", 1)  # 右から1回だけ分割。パスとファイル名に分割
['/path/to/foo/bar', 'hoge.txt']

余談ですがファイル名とパスに分割する機能は、os.path.split() を使った方がよいです。

文字列の置換 (単純置換・正規表現置換) re.sub replace regexp

単純置換

>>> "spam".replace("pa", "PA")
'sPAm'

正規表現置換

re.sub(pattern, repl, string)

>>> re.sub(r'[\d]+', "abc", "A123B")
'AabcB'

後方参照 \1, \2 … で参照可能。
raw文字列で指定しないと、文字列のエスケープ文字とみなされるので、\1 がアスキーコード 0x01 に置換されてしまう。raw文字列にしておくのが無難。

>>> re.sub(r'(\d)(\d+)', r"abc\1-\2", "A123B")
'Aabc1-23B'

関数で置換文字列生成。関数の引数mにマッチングオブジェクトが入る。

>>> def func(m):
...   n=int(m.group())
...   return str(n*2)
... 
>>> re.sub(r'(\d+)', func, "A128B")
'A256B'

同様にlambda式で。

>>> >>> re.sub(r'(\d+)', lambda m:str(int(m.group())*3), "A123B")
'A369B'

文字列検索系メソッド find, index, startswith, endswidth

find: 部分文字列を検索

指定した文字列内から、引数で与えた文字列が見つかるindexを返す。見つからない場合は−1を返す。

>>> "spam".find("pa")
1
>>> "spam".find("x")
-1

indexは見つからない場合にエラーを返す。

>>> "spam".index("pa")
1
>>> "spam".index("x")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found

startswith: 指定した文字列で始まるかどうか?

>>> "spam".startswith("sp")
True
>>> "spam".startswith("pa")
False

endswith: 指定した文字列で終了するかどうか?

>>> "spam".endswith("am")
True
>>> "spam".endswith("x")
False

日付の差分を取得

日付の差分を秒で取得する。


import datetime
t1 = datetime.datetime.now()  #time1
(datetime.datetime.now() - t1).total_seconds()  #現在時刻 - time1を秒で

例:


>>> import datetime
>>> t1 = datetime.datetime.now() 
>>> (datetime.datetime.now() - t1).total_seconds() 
3

差分はtimedeltaオブジェクトとして取得できるので、total_secondsメソッドで差分の秒数を取得できる。

timedeltaオブジェクトのsecondsフィールドがあるが、これは差分を日数、秒数、マイクロ秒数、ミリ秒数、分、時間、週で分解した要素の一つとしての秒数なので、差分を病であわら市たものではないので注意。

8.1. datetime — 基本的な日付型および時間型 — Python 3.5.1 ドキュメント

ランダムにn桁の文字列を作成

import random
source_str = 'abcdefghijklmnopqrstuvwxyz'

#a〜zでランダムに1文字
random.choice(source_str)  

#ランダムchoiceを10回繰り返し、
#リスト内包表記でリスト化したものを空文字でjoin
"".join([random.choice(source_str) for x in xrange(10)]) 

例:

>>> import random
>>> source_str = 'abcdefghijklmnopqrstuvwxyz'
>>> random.choice(source_str)
't'
>>> "".join([random.choice(source_str) for x in xrange(10)])
'eojutxvyaz'
>>> 

ハッシュ文字列生成

ハッシュコード生成

import hashlib
hashlib.md5("hoghoge").hexdigest()
hashlib.sha256("hoghoge").hexdigest()

例:

>>> import hashlib
>>> hashlib.md5("hoghoge").hexdigest()
'f45519c54a6bc7a2d2f1dd683ab26e97'
>>> hashlib.sha256("hoghoge").hexdigest()
'dee34d12c3f17d56b39d3211d1767b5e4c7c990d702e9f38a9d35c6b3df08893'

日付フォーマット(datetime⇔文字列)

datetime → 書式化文字列

>>> import datetime
>>> now = datetime.datetime.now()
>>> now.strftime("%Y/%m/%d %H:%M:%S")
'2012/01/01 20:29:39'

もしくは、新しい形式のformat関数を使ってもできる。

>>> "{0:%Y-%m-%d %H:%M:%S}".format(now)
'2012-10-07 08:15:03'

Python3.6以降からはフォーマット済み文字列リテラル(f-string)が使用可能なので、それを使うともっとかんたんにかける。

>>> f"{now:%Y-%m-%d %H:%M:%S}"
'2012-10-07 08:15:03'

その逆。書式化された日付文字列 → datetime

>>> import datetime
>>> datetime.datetime.strptime('2012/01/01 20:29:39', "%Y/%m/%d %H:%M:%S")
>>> datetime.datetime(2012, 1, 1, 20, 29, 39)

標準ライブラリではdatetimeモジュールのstrptimeが利用できるが、曜日や月の名称などでロケールに依存することがある。(Mon, 月など)
サードパーティ製モジュールのdatetutilを使って変換することもできる。

>>> import dateutil.parser
>>> dateutil.parser.parse('Tue Apr 10 04:54:42 JST 2007')
datetime.datetime(2007, 4, 10, 4, 54, 42, tzinfo=tzlocal())

フォーマット文字列はここを参照。
https://docs.python.org/ja/3/library/time.html#time.strftime

Directive Meaning Notes
%a ロケールにおける省略形の曜日名。
%A ロケールにおける省略なしの曜日名。
%b ロケールにおける省略形の月名。
%B ロケールにおける省略なしの月名。
%c ロケールにおける適切な日付および時刻表現。
%d 月の始めから何日目かを表す 10 進数 [01,31]。
%H (24 時間計での) 時を表す 10 進数 [00,23]。
%I (12 時間計での) 時を表す 10 進数 [01,12]。
%j 年の初めから何日目かを表す 10 進数 [001,366]。
%m 月を表す 10 進数 [01,12]。
%M 分を表す 10 進数 [00,59]。
%p ロケールにおける AM または PM に対応する文字列。 (1)
%S 秒を表す 10 進数 [00,61]。 (2)
%U 年の初めから何週目か (日曜を週の始まりとします)を表す
10 進数 [00,53]。年が明けてから最初の日曜日までの全ての
曜日は 0 週目に属すると見なされます。
(3)
%w 曜日を表す 10 進数 [0(日曜日),6]。
%W 年の初めから何週目か (日曜を週の始まりとします)を表す
10 進数 [00,53]。年が明けてから最初の月曜日までの全ての
曜日は 0 週目に属すると見なされます。
(3)
%x ロケールにおける適切な日付の表現。
%X ロケールにおける適切な時刻の表現。
%y 上 2 桁なしの西暦年を表す 10 進数 [00,99]。
%Y 上 2 桁付きの西暦年を表す 10 進数。
%Z タイムゾーンの名前 (タイムゾーンがない場合には空文字列)。
%% 文字 “%” 自体の表現。

文字列の正規表現split

文字列を正規表現で分割して、文字列配列にする。

import re
str_array = re.split(r'regexp', somstring)

>>> import re
>>> re.split(r'[,:]', "a,b:c")
['a', 'b', 'c']

forループなどで何度も繰り返すときには正規表現のコンパイルして、正規表現パターンオブジェクトを取得したほうが高速に動作する。

>>> import re
>>> ptn = re.compile(r'[,:]')
>>> ptn.split("a,b:c")   # コンパイル済みの正規表現パターンを使用する
['a', 'b', 'c']