заменить итерацию в Python - PullRequest
0 голосов
/ 07 февраля 2019

Я хотел бы заменить вхождения строки на другие значения (из словаря).

string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {1: 'hi', 2: 'there', 3: 'bla'}

Ожидается:

string = 'asfd hi fdsfd there ffds bla asdf'

Я пробовал несколько решений, особенно с .replaceили повторно, но все еще не нашел хорошего.

Ответы [ 6 ]

0 голосов
/ 07 февраля 2019

Вы можете использовать re.sub, чтобы выполнить работу без какой-либо сортировки.

Вернуть полученную строку, заменив крайние левые не перекрывающиеся вхождения шаблона в строке заменой repl.Если шаблон не найден, строка возвращается без изменений.repl может быть строкой или функцией;если это строка, обрабатываются все символы обратной косой черты в ней.

import re
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {'1': 'hi', '2': 'there', '3': 'bla'}
class repl:
    def __init__(self):
        self.called=0
    def __call__(self,match):
        self.called+=1
        return kv[str(self.called)]
print(re.sub('@@@',repl(),string))

OUTPUT

asfd hi fdsfd there ffds bla asdf
0 голосов
/ 07 февраля 2019
import re
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {1: 'hi', 2: 'there', 3: 'bla'}
counter = 1
def data_():
    global counter
    str_replace = kv[counter]
    counter += 1
    return str_replace
print(re.sub(r'@@@', data_(), string))
>>> asfd hi fdsfd there ffds bla asdf
0 голосов
/ 07 февраля 2019
kv = {'1': 'hi', '2': 'there', '3': 'bla'}
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
string_list=string.split('@@@')
string_list_out=[]
for i in range(len(string_list)):
    if i==0:
        string_list_out.append(string_list[0])
    else:
        string_list_out.append(kv[str(i)])
        string_list_out.append(string_list[i])

string_list_out=''.join(string_list_out)
print(string_list_out)
   'asfd hi fdsfd there ffds bla asdf'
0 голосов
/ 07 февраля 2019
string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {1: 'hi', 2: 'there', 3: 'bla'}

for k,v in kv.items():
    string = string.replace('@@@', v, 1)
print(string)

ВЫХОД:

asfd hi fdsfd there ffds bla asdf
0 голосов
/ 07 февраля 2019

Однострочное решение:

string.replace('@@@', '{}', len(kv)).format(*kv.values())

Краткое объяснение:

  • Заменить все строки '@@@' на идентификатор форматирования строки python '{}'.len(kv) уменьшает количество замен до длины dict, избегая IndexError, когда в dict меньше элементов, чем число '@@@' в строке
  • извлекает значения словаря с помощью kv.values()
  • распаковывает значения словаря с помощью *kv.values() и передает это в качестве аргумента методу string format.

Пример выполнения кода:
Ввод

string = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {'1': 'hi', '2': 'there', '3': 'bla'}

И вывод

string.replace('@@@', '{}', len(kv)).format(*kv.values())
#Out: 'asfd hi fdsfd there ffds bla asdf'

Преимущество этого решения: нет явного зацикливания (явное зацикливание почти всегда плохая идея в python) и только одна строка кода.Кроме того, также работает , когда число '@@@' меньше ** или больше, чем число значений в kv**, когда параметр count в str.replace указано.


Это приводит к окончательному и 99% отказоустойчивому варианту моего решения с использованием len изречения в качестве count аргумент в replace:

string.replace('@@@', '{}', len(kv)).format(*kv.values())
0 голосов
/ 07 февраля 2019

Это один подход с использованием str.replace с необязательным параметром count.

Пример:

s = 'asfd @@@ fdsfd @@@ ffds @@@ asdf'
kv = {'1': 'hi', '2': 'there', '3': 'bla'}

for k, v in sorted(kv.items()):
    s = s.replace("@@@", v, 1)
print(s)

MoreInfo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...