6 votes

Comment remplacer une chaîne vide par 0, mais ne pas la modifier si elle n'est pas vide ?

Le comportement de Python semble incohérent lors du remplacement de valeurs dans le cas suivant (avec python 3.6.5)

    >>> emptyString = '    '
    >>> emptyString.strip().replace('','0') #produces expected results
    '0'
    >>> notEmptyString = ' 50 '
    >>> notEmptyString.strip().replace('','0') #expected '50'
    '05000'
    >>> shortString = notEmptyString.strip()
    >>> shortString  #results as expected
    '50'
    >>> shortString.replace('','0') #unexpected results - expected '50'
    '05000'

C'est ce que j'aimerais voir :

  • si la chaîne a une valeur, il suffit de supprimer() les espaces avant et après.
  • si la chaîne de caractères est vide (c'est-à-dire "") ou si elle ne contient que des caractères vides (c'est-à-dire " "), elle est supprimée pour devenir "" et remplacée par '0'.

Exemple #1... string = " 10 ".... alors il suffit d'enlever le début et la fin de la chaîne. les espaces avant et après
Exemple n° 2... string = ' ' .... puis convertir en '0'

Je peux obtenir les résultats que je veux par d'autres moyens, mais je me demandais si quelqu'un comprenait pourquoi python produit ces résultats.

1 votes

Vous voulez peut-être définir une fonction qui fait quelque chose comme def myreplace(string): return string if string.strip() else '0'

6voto

K. A. Buhr Points 14622

Si s est une chaîne de caractères, alors :

s.replace(old, new)

renvoie une copie de s avec chaque occurrence de la chaîne old remplacé par new Ainsi, par exemple :

In [7]: "abracadabra".replace("a","4")
Out[7]: '4br4c4d4br4'

Dans un cas particulier, si old est la chaîne vide, il insère new au début et à la fin de la chaîne et entre chaque paire de caractères :

In [8]: "12345678".replace("","_")
Out[8]: '_1_2_3_4_5_6_7_8_'

Le raisonnement est qu'il y a une "chaîne vide" avant le premier caractère, entre chaque paire de caractères et après le dernier caractère, et c'est ce qui est remplacé.

Donc, replace ne fait pas ce que vous pensiez.

Pour faire ce que vous voulez, vous pouvez utiliser l'une des solutions déjà proposées, ou quelque chose comme ceci si vous vous sentez intelligent :

s.strip() or "0"

3voto

Sweeper Points 1267

Ceci est lié à la façon dont replace travaux.

Il s'agit de parcourir chaque index de la chaîne et de créer une sous-chaîne à partir de chaque index. Ensuite, elle vérifie si l'une des sous-chaînes commence par la chaîne à rechercher. Il enregistre ensuite l'indice des sous-chaînes qui commencent par la chaîne à rechercher, supprime la chaîne à rechercher et insère la chaîne de remplacement à ces indices.

Pour '' il n'y a qu'un seul index à parcourir, et la sous-chaîne qui commence à partir de cet index est '' qui commence par '' et un 0 est donc inséré.

Pour 50 il y a 3 indices à consulter. Les sous-chaînes à partir des indices sont :

'50'
'0'
''

Toutes ces sous-chaînes commencent par '' donc un 0 est inséré dans tous les indices, ce qui crée '05000' .

3voto

Olivier Melançon Points 15762

Comment str.replace travaux

Vous interprétez la méthode str.replace comme s'il remplaçait la chaîne entière par la nouvelle valeur. Or, ce n'est pas le cas.

Ce qu'il fait, c'est remplacer toutes les occurrences du premier argument par le deuxième argument dans la chaîne.

'ababc'.replace('ab', 'x') # 'xxc'

Ce qui peut prêter à confusion ici, c'est que vous remplacez toutes les occurrences de la balise chaîne vide . Il s'avère que la chaîne vide est présente partout, entre chaque deux caractères se trouve une chaîne vide.

Si cela n'a pas de sens pour vous, considérez que ce qui suit est en effet True

'' + '5' + '' + '0' + '' == '50'

Donc, en faisant ça...

s.replace('', '0')

Est équivalent à l'insertion de '0' entre tous les personnages. Il est équivalent à ce qui suit.

'0'.join(s.split())

Comment transformer une chaîne vide en une valeur par défaut

Ce que vous voulez faire, c'est dépouiller votre chaîne et la rendre '0' s'il est vide, voici quelques moyens de le faire.

# 1)
s = emptyString.strip()
s = s if s else '0'

# 2)
s = emptyString.strip() or '0'

2voto

Sociopath Points 3139

Comme @coldspeed l'a suggéré dans le commentaire, vous avez besoin :

def myfunc(string): return string if string.strip() else '0'

print(myfunc(' 050  '))
print(myfunc('   '))
print(myfunc(''))
print(myfunc('abcd'))

Sortie :

 050  
0
0
abcd

1 votes

Je pense que l'OP peut déjà résoudre son problème, mais il ne comprend pas pourquoi. replace se comporte de la sorte.

2voto

U9-Forward Points 8640

Une autre façon de procéder :

def f(s):
    return {'':'0'}.get(s.strip(),s)
print(f('   '))
print(f(' a '))

Sortie :

0
 a

Explication (pour str.replace) :

  1. str.replace(..) remplace la première arg par la seconde arg
  2. également "" est toujours dans une chaîne (pour voir ce que je veux dire 'ab'.count('') retours 3)

Explication (pour mon exemple) :

  1. Je crée un def (fonction)
  2. Ensuite, je fais une dictée
  3. Ensuite, je fais dict.get pour le contrôle

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X