web-dev-qa-db-fra.com

Comment soustraire des chaînes dans python

Fondamentalement, si j'ai une chaîne 'AJ' et une autre chaîne 'AJYF', J'aimerais pouvoir écrire 'AJYF'-'AJ' et obtenir 'YF'.

J'ai essayé mais j'ai eu une erreur de syntaxe.

Juste à côté, le soustracteur sera toujours plus court que la chaîne dont il est soustrait. De plus, le soustracteur sera toujours comme la chaîne dont il est soustrait. Par exemple, si j'ai "GTYF" et que je veux en soustraire une chaîne de longueur 3, cette chaîne doit être "GTY".

Si c'est possible, la fonction complète que j'essaie de faire est de convertir une chaîne en liste en fonction de la durée de chaque élément de la liste. Y a-t-il un moyen de le faire?

8
jay a

La solution facile est:

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

Je pense que ce que vous voulez c'est:

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

replace peut faire quelque chose que vous ne voulez pas si la deuxième chaîne est présente à plusieurs positions:

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

Vous pouvez ajouter un argument supplémentaire à replace pour indiquer que vous souhaitez qu'un seul remplacement se produise:

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

Ou vous pouvez utiliser le module re:

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

Le '^' Est destiné à garantir que s2 Ne soit substitué qu'à la première position de s1.

Une autre approche, suggérée dans les commentaires, consisterait à retirer les premiers len(s2) caractères de s1:

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

Certains tests utilisant la magie% timeit dans ipython (python 2.7.12, ipython 5.1.0) suggèrent que cette dernière approche est plus rapide:

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

si vous insistez pour utiliser l'opérateur '-', utilisez une classe avec la méthode dunder __ sub __ écrasée, avec une combinaison de l'une des solutions fournies ci-dessus:

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)

Il imprime:

YF
F
0
ttbsttsoo