web-dev-qa-db-fra.com

pouvez-vous écrire un str.replace () en utilisant les valeurs du dictionnaire en Python?

Je dois remplacer le nord, le sud, etc. par N S dans les champs d'adresse.

Si j'ai

list = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
address = "123 north anywhere street"

Puis-je parcourir les valeurs de mon dictionnaire pour remplacer mon champ d'adresse?

for dir in list[]:
   address.upper().replace(key,value)

Je sais que je ne suis même pas proche !! Mais toute entrée serait appréciée si vous pouviez utiliser des valeurs de dictionnaire telles que celle-ci.

12
user1947457
address = "123 north anywhere street"

for Word, initial in {"NORTH":"N", "SOUTH":"S" }.items():
    address = address.replace(Word.lower(), initial)
print address

Sympa et concis et lisible aussi.

10
rikAtee

vous êtes proches, en fait:

dictionary = {"NORTH":"N", "SOUTH":"S" } 
for key in dictionary.iterkeys():
    address.upper().replace(key, dictionary[key])

Remarque: pour les utilisateurs de Python 3, vous devez utiliser .keys() au lieu de .iterkeys():

dictionary = {"NORTH":"N", "SOUTH":"S" } 
for key in dictionary.keys():
    address.upper().replace(key, dictionary[key])
3
Samuele Mattiuzzo

Vous recherchez probablement iteritems():

d = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
address = "123 north anywhere street"

for k,v in d.iteritems():
    address = address.upper().replace(k, v)

l'adresse est maintenant '123 N ANYWHERE STREET'


Eh bien, si vous souhaitez conserver la casse, les espaces et les mots imbriqués (par exemple, Southstreet ne doit pas être converti en Sstreet), envisagez d'utiliser cette compréhension de liste simple:

import re

l = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}

address = "North 123 East Anywhere Southstreet    West"

new_address = ''.join(l[p.upper()] if p.upper() in l else p for p in re.split(r'(\W+)', address))

new_address is now 

N 123 E Anywhere Southstreet    W
1
sloth
def replace_values_in_string(text, args_dict):
    for key in args_dict.keys():
        text = text.replace(key, str(args_dict[key]))
    return text
1
Artem Malikov

Une option que je ne pense pas que quiconque ait encore suggérée consiste à créer une expression régulière contenant toutes les clés, puis de simplement remplacer la chaîne:

>>> import re
>>> l = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
>>> pattern = '|'.join(sorted(re.escape(k) for k in l))
>>> address = "123 north anywhere street"
>>> re.sub(pattern, lambda m: l.get(m.group(0).upper()), address, flags=re.IGNORECASE)
'123 N anywhere street'
>>> 

Cela présente l'avantage que l'expression régulière peut ignorer la casse de la chaîne d'entrée sans la modifier.

Si vous souhaitez utiliser uniquement des mots complets, vous pouvez également le faire avec une simple modification du motif:

>>> pattern = r'\b({})\b'.format('|'.join(sorted(re.escape(k) for k in l)))
>>> address2 = "123 north anywhere southstreet"
>>> re.sub(pattern, lambda m: l.get(m.group(0).upper()), address2, flags=re.IGNORECASE)
'123 N anywhere southstreet'
1
Duncan

Toutes ces réponses sont bonnes, mais il vous manque la substitution de chaîne python - c'est simple et rapide, mais votre chaîne doit être correctement formatée.

address = "123 %(direction)s anywhere street"
print(address % {"direction": "N"})
1
Anna

"Traduire" une chaîne avec un dictionnaire est une exigence très courante. Je propose une fonction que vous voudrez peut-être conserver dans votre boîte à outils:

def translate(text, conversion_dict, before=None):
    """
    Translate words from a text using a conversion dictionary

    Arguments:
        text: the text to be translated
        conversion_dict: the conversion dictionary
        before: a function to transform the input
        (by default it will to a lowercase)
    """
    # if empty:
    if not text: return text
    # preliminary transformation:
    before = before or str.lower
    t = before(text)
    for key, value in conversion_dict.items():
        t = t.replace(key, value)
    return t

Ensuite, vous pouvez écrire:

>>> a = {'hello':'bonjour', 'world':'tout-le-monde'}
>>> translate('hello world', a)
'bonjour tout-le-monde'
1
fralau

Les fonctions replace() et format() ne sont pas aussi précises:

data =  '{content} {address}'
for k,v in {"{content}":"some {address}", "{address}":"New York" }.items():
    data = data.replace(k,v)
# results: some New York New York

'{ {content} {address}'.format(**{'content':'str1', 'address':'str2'})
# results: ValueError: unexpected '{' in field name

Il est préférable de traduire avec re.sub() si vous avez besoin de endroit précis :

import re
def translate(text, kw, ignore_case=False):
    search_keys = map(lambda x:re.escape(x), kw.keys())
    if ignore_case:
        kw = {k.lower():kw[k] for k in kw}
        regex = re.compile('|'.join(search_keys), re.IGNORECASE)
        res = regex.sub( lambda m:kw[m.group().lower()], text)
    else:
        regex = re.compile('|'.join(search_keys))
        res = regex.sub( lambda m:kw[m.group()], text)

    return res

#'score: 99.5% name:%(name)s' %{'name':'foo'}
res = translate( 'score: 99.5% name:{name}', {'{name}':'foo'})
print(res)

res = translate( 'score: 99.5% name:{NAME}', {'{name}':'foo'}, ignore_case=True)
print(res)
0
ahuigo

Essayer, 

import re
l = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}

address = "123 north anywhere street"

for k, v in l.iteritems():
    t = re.compile(re.escape(k), re.IGNORECASE)
    address = t.sub(v, address)
print(address)
0
Adem Öztaş