web-dev-qa-db-ja.com

pythonで文字列を減算する方法

基本的に、文字列'AJ'と別の文字列'AJYF'がある場合、'AJYF'-'AJ'を記述して'YF'を取得できます。

これを試しましたが、構文エラーが発生しました。

念のため、減算器は常に、減算される文字列よりも短くなります。また、減算器は常に減算元の文字列のようになります。たとえば、「GTYF」があり、そこから長さ3の文字列を減算する場合、その文字列は「GTY」でなければなりません。

可能であれば、私がしようとしている完全な機能は、リスト内の各アイテムの長さに基づいて文字列をリストに変換することです。それを行う方法はありますか?

8
jay a

簡単な解決策は次のとおりです。

>>> string1 = 'AJYF'
>>> string2 = 'AJ'
>>> if string2 in string1:
...     string1.replace(string2,'')
'YF'
>>>
15
Shubham Namdeo

あなたが欲しいのはこれだと思います:

a = 'AJYF'
b = a.replace('AJ', '')
print a     # produces 'YF'
a = 'GTYF'
b = a.replace('GTY', '')
print a     # produces 'F'
6
Tom Barron

replaceは、2番目の文字列が複数の位置にある場合、望ましくないことを実行できます。

_s1 = 'AJYFAJYF'
s2 = 'AJ'
if s1.startswith(s2):
    s3 = s1.replace(s2, '')
s3
# 'YFYF'
_

replaceに追加の引数を追加して、1つの置換のみを実行することを示すことができます。

_if s1.startswith(s2):
    s3 = s1.replace(s2, '', 1)
s3
# 'YFAJYF'
_

または、reモジュールを使用できます。

_import re
if s1.startswith(s2):
    s3 = re.sub('^' + s2, '', s1)
s3
# 'YFAJYF'
_

_'^'_は、_s2_が_s1_の最初の位置でのみ置換されるようにするためのものです。

コメントで提案されているさらに別のアプローチは、_s1_から最初のlen(s2)文字を取り出すことです。

_if s1.startswith(s2):
    s3 = s1[len(s2):] 
s3
# 'YFAJYF'
_

Ipythonの%timeitマジック(python 2.7.12、ipython 5.1.0)を使用したいくつかのテストは、この最後のアプローチがより高速であることを示唆しています。

_In [1]: s1 = 'AJYFAJYF'

In [2]: s2 = 'AJ'

In [3]: %timeit s3 = s1[len(s2):]
The slowest run took 24.47 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 87.7 ns per loop

In [4]: %timeit s3 = s1[len(s2):]
The slowest run took 32.58 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 87.8 ns per loop

In [5]: %timeit s3 = s1[len(s2):]
The slowest run took 21.81 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 87.4 ns per loop

In [6]: %timeit s3 = s1.replace(s2, '', 1)
The slowest run took 17.64 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 230 ns per loop

In [7]: %timeit s3 = s1.replace(s2, '', 1)
The slowest run took 17.79 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 228 ns per loop

In [8]: %timeit s3 = s1.replace(s2, '', 1)
The slowest run took 16.27 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 234 ns per loop

In [9]: import re

In [10]: %timeit s3 = re.sub('^' + s2, '', s1)
The slowest run took 82.02 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.85 µs per loop

In [11]: %timeit s3 = re.sub('^' + s2, '', s1)
The slowest run took 12.82 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.86 µs per loop

In [12]: %timeit s3 = re.sub('^' + s2, '', s1)
The slowest run took 13.08 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.84 µs per loop
_
4
bli

「-」演算子の使用を主張する場合は、上記のソリューションのいずれかを組み合わせて、__ sub __ dunderメソッドをオーバーライドしたクラスを使用します。

class String(object):
    def __init__(self, string):
        self.string = string

    def __sub__(self, other):
        if self.string.startswith(other.string):
            return self.string[len(other.string):]

    def __str__(self):
        return self.string


sub1 = String('AJYF') - String('AJ')
sub2 = String('GTYF') - String('GTY')
print(sub1)
print(sub2)

以下を印刷します。

YF
F
0
ttbsttsoo