Pythonができる文字列の事。上巻:文字列の基本

Pythonにおける文字列の扱い方

この記事の開発環境

  • バージョン: Python3.8
  • IDE: spacemacs with paython-layer
  • ライブラリ:標準ライブラリ、jedi、ipython、yapf、flake8などなど
  • 環境構築: pyenv、pyenv-virtualenv
  • OS: macOS & ubuntu 18.04

文字列の基本

文字列の扱いがPythonでどのように行われるのか見ていこう。 テキストデータは「strオブジェクト」と呼ばれるいわゆる文字列で、指定がない限り「UTF-8」となる。この文字列は変更不可能体:immutableとなっている。テキストシーケンス型ともいう。

文字列の実証ソースコード

# ***文字列の宣言***
mojimoji1 = '神は言っている。ここので死ぬ定めではないと。'
mojimoji2 = "各いう私も童貞でね。"

# シングルクォートを文字として出力
mojimoji3 = "I'm so happy."
# ダブルクォートを文字として出力
mojimoji4 = '田中敦彦曰く"人生は祭りだ"'

# 三連引用符
mojimoji5 = """I am GODS child
こんなものの
ために生まれたんじゃない
"""

# 三連引用符をソースコード上見やすくする、改行させない出力
mojimoji6 = """\
I am GODS child
こんなものの
ために生まれたんじゃない
&"""
# 文字列をメソッド無しで結合
mojimoji7 = "ABC" "DEF"
mojimoji8 = mojimoji2 + mojimoji3
mojimoji9 = mojimoji2 + "Hello."

# 長い文字列をソースコード上見やすくする
mojimoji10 = "聡明な伴侶を得られれば得よ。得られぬならば孤独に暮らせ。"
"悪をなさず。求めるところは少なく。林の中の象のように。ーーー仏陀"

# ***エスケープ文字***
"""
改行:\n
復帰:\r
垂直タブ:\f
ダブル:\"
シングル:\'
タブ:\t
バックスラッシュ:\\
"""

# ***文字列のインデックス指定***
index_str = "I heard there was secret code."
# 始まりは0から
index_str[0]
# マイナスのインデックスも受け付ける
index_str[-8]

# ***スライシング***
index_str[3:6]
# マイナスでもいけます
index_str[3:-7]
# 終わりがなげければ最後まで出力する
index_str[3:]
# 始まりがなければ最初から出力する
index_str[:12]
# 終わりが範囲外でもなんとかしてくれる
index_str[3:30]
# 始まりが範囲外では空文字を返し、エラーとはならない。
index_str[30:40]

文字列の基礎コードの実行結果

Python文字列操作の実行結果1
Python文字列操作の実行結果1
PythonができるStringの事。実行結果2。
PythonができるStringの事。実行結果2。

実行結果を解説

文字列の宣言:文字列はシングルクォートかダブルクォートで囲うか、3つ繋げた三連引用符を用いて行う。 またPythonでは+演算子を用いなくとも文字列同士であれば並べて書くことで連結できる。長い文章をソースコード内に入れる必要がある場合に可読性において便利と言える。この場合改行が入ったりはしない。 三連引用符内では改行がそのまま反映される。これを避けたい場合は行末に「\」を置くことで回避できる。つまり”””の次の行から文字列を入れると、1行目は改行が入り2行目から文字列が出力されることになるので、「\」でこれを回避できるという事である。

エスケープ文字:記号としてシングルまたはダブルクォートを使いたい場合はお互いを中に入れることで実現できる。あるいはクォートの直前に「r」をつけて宣言する(r”I’m happy”、などどする)ことで中にある記号やエスケープ文字をそのまま(生の)文字列として出力できる。 以下にエスケープ文字をあげてみる。

  • \n 改行
  • \r 復帰        正直復帰の使い所が分からぬ。
  • \n\r 改行復帰
  • \v 垂直タブ      垂直タブも分からぬ。
  • \f 改ページ
  • \’ シングルクォート
  • \” ダブルクォート
  • \t  タブ
  • \\  バックスラッシュ

コメント:Pythonのコメントは「 #」を用いて行う。そのほか先にあげた三連引用符も使う。三連引用符はいわゆるアノテーションであり、pythonではDocstringという。Docstringは推奨される書き方があるのでこれはまた別の記事で取り上げたい。 ちなみにPEPによると、コメントは#のあとに半角スペースを入れることが推奨されている。

インデックス指定:インデックスを指定することで文字を指定して返すことができる。この場合は文字列を変数に代入し、変数[3]という形で扱う。インデックスはマイナスの値でも指定可能である。インデックスは例によって例の如く0始まりである。

インデックスは文字の場所と考えると少し違う。インデックスは文字と文字の間にあるものだ。0は行頭の文字の左に位置し、1は行頭の文字の右側に位置する。よってインデックスが−1の場合は行末の文字の左となり行末の文字を指すことにな離、マイナスになってもインデックスの右隣の文字が対象となる。マイナスを指定した後、左方向へ向かっていくようなことはない。

スライシング:文字列は始まりと終わりを指定して切り出すことができる。指定したインデックス内の文字列が返り値となる。インデックス指定の時と同じように、変数[3:8]という形で行う。 スライシングでもマイナスのインデックス指定ができる。動作は上記インデックス指定と同じである。

ちなみにスライシングでは文字列が20文字であっても、範囲外の例えば32などをインデックスに指定しても問題なく処理してくれる。 始まりが範囲外のとき空文字を返し、終わりが範囲外のとき存在するところまでを返す。

プログラミング用語解説

  • シーケンス: 連続している、順序、順番、配列などの意味がある。テキストシーケンスは文字配列と言える。
  • リテラル: ソースコード内に直に書かれた値そのもの。 ”ABC”や、num = 150の150などのこと。
  • アノテーション: ノテーション英語:annotation)とは、あるデータに対して関連する情報(メタデータ)を注釈として付与すること。XML等の記述形式を用いてメタデータをタグ付けする場合が多い。付与したメタデータやタグを指してアノテーションという場合もある。Wikipediaより抜粋

文字列に対して共通のシーケンス演算を使う。

Pythonシーケンス演算一覧

  • in 有るならTrue
  • not in 無いならTrue
  • + 左右を結合する
  • * moji * 10 などとすることで文字を繰り返す。この場合は10回。
  • [2] インデックス指定
  • [2:3] スライシング
  • [2:31:2] スライシングの3目の引数はステップを指定する。2の場合は1個飛ばしとなる。
  • len() 引数に指定されたものの長さ、文字列なら文字数
  • min() 引数の最小値を返す。文字列の場合は半角全角、漢字、ひらがな、カタカナ、記号などで決まっている模様。
  • max() 引数の最大値を返す。文字列の場合は上記と同じ原理。
  • str.index(moji, 3, 35) 第1引数が出現するインデックス番号を返す。第2、3引数はスライシングと同じ要領。
  • .str.count() 引数が含まれる数を返す。

文字列と共通シーケンス演算 実演ソースコード

# ***inとnot in***
str_1 = "ABCDEFGHIJKLMN"
# 在るとtrue
"GHI" in str_1
# 無いとfalse
"BCA" in str_1
# 無いとtrue
"Z" not in str_1
# 在るとfalse
"M" not in str_1

# ***スライシングのステップ***
# 1個飛ばし
str_1[2:13:2]

# ***len(),min(),max()***
len(str_1)
min(str_1)
max(str_1)
# ***index()始まりを知る***
str_1.index("G", 2, 13)
str_1.index("G", 2, 5) #ValueError

# ***count()何個あるか数える***
str_1.count() #TypeError
str_1.count("B")
str_1.count("Z")

共通シーケンス演算の実行結果

実行結果解説

 共通ということでシーケンス型であれば使える。in演算子とnot in演算子の返り値はBool値となる。実行してみてわかったが返り値がBool値でも、別段str()で文字列変換する必要がないようだ。

スライシングの第3引数にはデフォルトで1が入っている。2で1個飛ばしに、3で2個飛ばしになる。使い所がいまいち分からないがとにかうそういうことだ。

len()は文字数が返ってくる。min()は正直ルールが面倒だが、漢字と記号だと記号になる。max()はその逆となる。半角英字ならAが小さくZが大きいようだ。だからどうした。

一番謎なのが、index()である。存在しない場合はエラーとなる仕様は一体なんのためなのか。

意外なのが、count()で、引数がないとエラーとなる。他の言語だとない時は0となる気がするが。

コメントする