Pythonで文字列の部分文字列を取得するにはどうすればよいですか?


2144

Pythonで文字列を部分文字列化して、3番目の文字から文字列の末尾までの新しい文字列を取得する方法はありますか?

たぶんmyString[2:end]

2番目の部分を残すことは「終わりまで」を意味し、1番目の部分を残す場合、それは最初から始まりますか?


1
これには明確な説明が含まれていますpythoncentral.io/cutting-and-slicing-strings-in-python
mario ruiz

回答:


3178
>>> x = "Hello World!"
>>> x[2:]
'llo World!'
>>> x[:2]
'He'
>>> x[:-2]
'Hello Worl'
>>> x[-2:]
'd!'
>>> x[2:-2]
'llo Worl'

Pythonはこの概念を「スライス」と呼び、文字列だけでなくそれ以外にも機能します。包括的な紹介については、こちらご覧ください。


401

他の誰もそれを言及していないので、完全を期すために。配列スライスの3番目のパラメーターはステップです。したがって、文字列の反転は次のように簡単です。

some_string[::-1]

または、代替文字の選択は次のようになります。

"H-e-l-l-o- -W-o-r-l-d"[::2] # outputs "Hello World"

文字列を前後に移動する機能により、スライスを最初または最後から配列できるため、一貫性が維持されます。


21
@mtahmedは質問に完全に関連しています。文字列から代替文字を選択して部分文字列にしたい場合はどうなりますか?my_string [:: 2]
エンドファージ

スライスする3番目のパラメーターについて言及したほうがよいと思います。文字列から他のすべての文字を取得する必要があることは、どこかで重要なユースケースかもしれませんが、私はそれをする必要がありませんでした。あなたが知っていることを自慢したいということに何か問題があるというわけではありません-あなたがそれを行うことができない場合に何かを知っていることの意味は何ですか?:)しかし、質問との関連性についての主張は誇張されています。
John Lockwood 2017

1
確かに、代替文字を選択する具体的な例は質問には関係ないかもしれませんが、非常に多くのスライスに3番目のパラメーターがあることを理解することは適切であり、単純な例はそれがどのように機能するかを示すのに役立ちます。Pythonコミュニティには、新しいメンバーを友好的な方法で教育してきた素晴らしい歴史もあります:-)
エンドファージ

127

Substr()は通常(つまり、PHPとPerl)は次のように動作します。

s = Substr(s, beginning, LENGTH)

したがって、パラメーターはbeginningおよびLENGTHです。

しかし、Pythonの動作は異なります。開始(END)の後(!)を期待しています。これは初心者にはわかりにくいものです。したがって、Substr(s、begining、LENGTH)の正しい置き換えは

s = s[ beginning : beginning + LENGTH]

76
初心者は、他の言語の習慣に固執するのではなく、pythonに移行するときにpythonicの方法を学ぶ必要があります
Nicu Surdu 2013年

3
また、完全を期すために、JavaはPythonに似ており、String.substring()メソッドが最初と最後を受け取ります。これは私を一生懸命噛みしめました、私はそれが世界の他のすべての部分文字列関数のような長さであると思っていました。
PhilHibbs

4
それを行うための(おそらく)よりパイソン的な方法はs[beginning:][:length]
victortv

2
PHPのような[ダーティーワード]言語ではなくPythonで始めた人として、Pythonはその文字列[beginning:end]を使用することで、はるかにシンプルで直感的になると思います。通常、長さは関係ありません。
-Gloweye、

60

これを実現する一般的な方法は、文字列のスライスです。

MyString[a:b] インデックスaから(b-1)までの部分文字列を取得します。


23

ここに1つの例が不足しているようです:完全な(浅い)コピー。

>>> x = "Hello World!"
>>> x
'Hello World!'
>>> x[:]
'Hello World!'
>>> x==x[:]
True
>>>

これは、(インターンされた文字列ではなく)シーケンス型のコピーを作成するための一般的なイディオムです[:]。Shallowはリストをコピーします明らかな理由もなく使用されているPythonリストスライス構文を参照してください。


12
これは、部分文字列に関する質問とはほとんど関係ありません。文字列にも適用されません。stringA = stringBで十分です...
Nicu Surdu 2013年

2
[:]フルコピーは新しいコピーを作成し、スライス構文を使用し、「開始から終了までの部分文字列」として読み取られます
gimel

2
文字列は不変なので、ポイントは何ですか?a=b十分なはずです。
bfontaine 16

1
@gimel:実際、[:]不変タイプではコピーはまったく作成されません。一方でmysequence[:]、ほとんど無害であるときmysequenceのような不変タイプでstrtuplebytes(PY3)またはunicode(PY2)は、a = b[:]と等価であるa = b、それはちょうどそれがとき浅いコピーには無意味なので、それ自体を返すことにそのオブジェクトが応答スライスバイトコードを派遣少し時間を浪費します、オブジェクトアイデンティティテストは別として、不変の自己への別の参照を返すのと同じです。
ShadowRanger 2017年

3
この回答に対する他の批判を要約しようとすると、Pythonでは文字列は不変であるため、文字列のコピーを作成する理由はありません。つまりs[:]、まったくコピーを作成しませんs = 'abc'; s0 = s[:]; assert s is s0。はい、それはリストが取得されるまでPythonでリストをコピーする慣用的な方法でしたlist.copyが、不変タイプの完全なスライスは変更できないため、コピーを作成する理由がありません。それをコピーする時間を無駄にしてはいけません。この答えは間違っていて、質問にも答えないので、削除する必要がありますか?
アーロンホール

18

Pythonで文字列を部分文字列化して、3番目の文字から文字列の末尾までの新しい文字列を取得する方法はありますか?

たぶんmyString[2:end]

はい、これは実際に、名前を定数シングルトンに割り当てる、つまりバインドする場合に機能します。endNone

>>> end = None
>>> myString = '1234567890'
>>> myString[2:end]
'34567890'

スライス表記には3つの重要な引数があります。

  • 開始
  • やめる
  • 一歩

指定しない場合のデフォルトはNone-ですが、明示的に渡すことができます。

>>> stop = step = None
>>> start = 2
>>> myString[start:stop:step]
'34567890'

第2部を離れることが「終わりまで」を意味する場合、第1部を離れると、それは最初から始まりますか?

はい、例えば:

>>> start = None
>>> stop = 2
>>> myString[start:stop:step]
'12'

スライスにはstartを含めますが、stopは含めずに、上にのみ移動することに注意してください。

stepがのNone場合、デフォルトではスライスは1ステップに使用します。負の整数でステップする場合、Pythonは十分に賢く、最後から最初に進みます。

>>> myString[::-1]
'0987654321'

スライス表記についての質問への回答、スライス表記について詳しく説明します。


8

「終了」を除いて、あなたはそれをそこに持っています。これはスライス表記と呼ばれます。あなたの例は次のようになります:

new_sub_string = myString[2:]

2番目のパラメーターを省略すると、暗黙的にストリングの終わりになります。


6

ディスカッションに2つのポイントを追加したいと思います。

  1. None代わりに空のスペースを使用して、「最初から」または「最後まで」を指定できます。

    'abcde'[2:None] == 'abcde'[2:] == 'cde'

    これは、引数として空のスペースを提供できない関数で特に役立ちます。

    def substring(s, start, end):
        """Remove `start` characters from the beginning and `end` 
        characters from the end of string `s`.
    
        Examples
        --------
        >>> substring('abcde', 0, 3)
        'abc'
        >>> substring('abcde', 1, None)
        'bcde'
        """
        return s[start:end]
  2. Pythonにはスライスオブジェクトがあります。

    idx = slice(2, None)
    'abcde'[idx] == 'abcde'[2:] == 'cde'

6

myStringにオフセット6から始まり、長さが9の口座番号が含まれている場合、口座番号を次のように抽出できますacct = myString[6:][:9]

OPがそれを受け入れた場合、実験的に試してみるとよいでしょう。

myString[2:][:999999]

動作します-エラーは発生せず、デフォルトの「文字列パディング」は発生しません。


1
myString[offset:][:length]OPの場合にこの方法を使用したい場合は、そのまま使用できますmyString[offset:][:]
victortv

1
@VictorVal答えは、Pythonを2番目(3番目、4番目、...)のプログラミング言語として学習し、使い慣れた「構文フック」を使用してその言語にアプローチしたい人(私のような)向けです。言語の専門家なら誰でも私の答えを少しばかげたものだと考えるでしょう。
CopyPasteIt

このような回答には削除のフラグを付ける必要がありますか?他の答えは同様の解決策をはるかによく説明しており、これを見ると頭が悩まされ、Pythonを数分間検索してから、それがそのタイプの答えであることを認識しました。
セビ

3

たぶんそれを逃したかもしれませんが、変数についてはここでは詳しく説明されていないため、このページで元の質問に対する完全な回答を見つけることができませんでした。それで私は捜索を続けなければなりませんでした。

私はまだコメントすることが許されていないので、ここに私の結論を付け加えましょう。このページにアクセスしたときに私が興味を持ったのは私だけではなかったと思います。

 >>>myString = 'Hello World'
 >>>end = 5

 >>>myString[2:end]
 'llo'

最初の部分を離れると、

 >>>myString[:end]
 'Hello' 

また、中央に:を残した場合、最も単純な部分文字列が得られます。これは5番目の文字になります(0から始まるので、この場合は空白です)。

 >>>myString[end]
 ' '

1

まあ、私はPHPスクリプトをPythonに変換する必要があり、の多くの使用法がある状況になりましたsubstr(string, beginning, LENGTH)
Pythonを選択した場合、多くの終了インデックスstring[beginning:end]を計算する必要があるため、を使用する方が簡単でしたがstring[beginning:][:length]、これにより多くの問題を解決できました。


0

ハードコード化されたインデックス自体を使用すると、混乱する可能性があります。

これを回避するために、Pythonには組み込みオブジェクトが用意されていますslice()

string = "my company has 1000$ on profit, but I lost 500$ gambling."

残りの金額を知りたい場合。

通常の解決策:

final = int(string[15:19]) - int(string[43:46])
print(final)
>>>500

スライスの使用:

EARNINGS = slice(15, 19)
LOSSES = slice(43, 46)
final = int(string[EARNINGS]) - int(string[LOSSES])
print(final)
>>>500

スライスを使用すると、読みやすくなります。


5
ハードコーディングされたインデックスが残り、読みやすさが最初の例で使用できた中間変数から得られるため、これは最良の例ではないかもしれません。
ASalazar 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.