Замените двухбуквенный код состояния полным именем в строке — Python 3.8.x

У меня есть список из ~60 тыс. строк, и все они выглядят так:

strings = ['corpus christi tx', 'san angelo', 'oklahoma city ok', 'abilenesweetwater']

У меня также есть dict поисковых запросов. Для MRE:

lookup = {'tx': 'texas', 'ny': 'new york', 'nj': 'new jersey', 'ok': 'oklahoma'}

Что я хотел бы сделать, так это прокрутить мой список строк и заменить двузначный код состояния на value в словаре, чтобы итоговый список выглядел так:

new_strings = ['corpus christi texas', 'san angelo', 'oklahoma city oklahoma', 'abilenesweetwater']

Я видел много подобных вопросов, которые пытаются сделать это, когда двузначный код штата (или полное название штата) является столбцом pd.Dataframe, но не как независимая строка. Я предполагаю, что мне понадобится regex.

Я пробовал следующее:

print("Test", 'corpus christi tx')
new_test_str = re.sub(r'[\s+tx+\s]', 'texas', 'corpus christi tx')
print("Reply", new_test_str)

Что (неправильно) дает:

Test corpus christi tx
Reply corpustexaschristexasitexastexastexas

ваше регулярное выражение неверно... [...] синтаксис - это класс символов, поэтому [\s+tx+\s] будет соответствовать каждому символу \s (пробел, табуляция и т. д.), каждому символу +, каждому символу t и x и заменит их целевой строкой

Anentropic 17.03.2022 15:00

Я в этом не сомневаюсь, но тогда на вопрос может ответить правильный re, который заполняет запрошенные результаты.

artemis 17.03.2022 15:01

чтобы заменить tx на texas, вы можете попробовать re.sub(r'\btx\b', 'texas', 'corpus christi tx') ... \b соответствует «границе слова», фактически не включая пробел в самом совпадении замены

Anentropic 17.03.2022 15:04
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
49
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете создать регулярное выражение из ключей словаря, чтобы сопоставить их как целые слова, и получить значения из словаря, как только совпадение будет найдено, и заменить это значение:

import re
strings = ['corpus christi tx', 'san angelo', 'oklahoma city ok', 'abilenesweetwater']
lookup = {'tx': 'texas', 'ny': 'new york', 'nj': 'new jersey', 'ok': 'oklahoma'}
rx =  re.compile(fr'\b(?:{"|".join([key for key in lookup])})\b')
strings = [rx.sub(lambda x: lookup[x.group()], s) for s in strings]

Выход:

>>> strings
['corpus christi texas', 'san angelo', 'oklahoma city oklahoma', 'abilenesweetwater']

См. онлайн-демонстрация Python.

Вот еще один подход к замене строк. Предполагая, что код состояния всегда находится в конце строки, вы пишете шаблон регулярного выражения для поиска таких строк и заменяете его значением в своем словаре поиска.

import re    
strings = ['corpus christi tx', 'san angelo', 'oklahoma city ok', 'abilenesweetwater']
lookup = {'tx': 'texas', 'ny': 'new york', 'nj': 'new jersey', 'ok': 'oklahoma'}
_patt = re.compile(r'\s(\w{2})$')

strings = [re.sub(_patt.search(s).group(1), lookup.get(_patt.search(s).group(1)), s) if _patt.search(s) else s for s in strings]

Выход:

['corpus christi texas', 'san angelo', 'oklahomalahoma city oklahoma', 'abilenesweetwater']

Чтобы понять этот код в деталях, вот более простая реализация того же кода:

for each in strings:
    match = _patt.search(each)
    if match:
        each = re.sub(match.group(1), lookup.get(match.group(1)), each)
        print(each)

Другие вопросы по теме