Я новичок в питоне. Я нашел вопрос в Python, что данная строка в формате "% 0 - это% 1% 2" и кортеж ("Ram", "good", "boy"). Строка означает, что содержит% x, где она должна быть заменена соответствующим элементом кортежа индекса x. (после редактирования): Забыл упомянуть, если данный кортеж («Ram», «good»)., ответ должен быть «Ram - хороший% 2», т.е. оставшиеся% x должны быть оставлены как есть.

Результат должен быть "Рам хороший мальчик". Я сделал это так (ниже код). Но я узнал, что это может быть написано более эффективным способом, в меньшей степени нет. из линий ... Не могли бы вы помочь, как? заранее спасибо

format = "%0 is a %1 %2"
args = ("Ram", "good", "boy")
count = 0
for i in range(0, len(format) + 1):
    if format[i] == '%':
        b= '%'
        b = b + format[i + 1]

        format = format.replace(b, args[int(format[i+1])])
        count+= 1

        if count == len(args):
            break

print format
1
Manoj Ch 14 Дек 2015 в 23:17

3 ответа

Лучший ответ

Я бы использовал str.format, вы можете просто распаковать кортеж:

args = ("Ram", "good", "boy")


print("{}  is a {} {}".format(*args))
Ram is  a good boy

Если вам нужно манипулировать исходной строкой, сначала используйте re.sub. :

import re

"%2 and %1 and %0"
 args = ("one", "two", "three")

print(re.sub(r"%\d+", lambda x: "{"+x.group()[1:]+"}", s).format(*args))

Выход:

In [6]: s = "%2 and %1 and %0"

In [7]: re.sub(r"%\d+", lambda x: "{"+x.group()[1:]+"}", s).format(*args)
Out[7]: 'three and two and one'

In [8]: s = "%1 and %0 and %2"

In [9]: re.sub(r"%\d+",lambda x: "{"+x.group()[1:]+"}", s).format(*args)
Out[9]: 'two and one and three'

%\d+ соответствует знаку процента, за которым следуют 1 или более цифр, x в лямбда-выражении - это объект соответствия, который мы используем .group, чтобы получить совпадающую строку и вырезать только те цифры, которые обертывают числовая строка в {} для использования в качестве заполнителей для str.format.

Напомним, что у вас может быть больше заполнителей, чем аргументов, sub принимает аргумент count максимального количества замен:

s = "%0 is a %1 %2"
args = ("Ram", "Good")
sub = re.sub(r"%\d+\b", lambda x: "{"+x.group()[1:]+"}", s,count=len(args)).format(*args)

print(sub)

Выход:

Ram is a Good %2

Для работы в произвольном порядке потребуется больше логики:

s = "%2 is a %1 %0"
args = ("Ram", "Good")

sub = re.sub(r"%\d+\b", lambda x: "{"+x.group()[1:]+"}" if int(x.group()[1:]) < len(args) else x.group(), s).format(*args)

print(sub)

Выход:

%2 is a Good Ram

Перемещение лямбда-логики в функцию немного приятнее:

s = "%2 is a %1 %0"
args = ("Ram", "Good")
def f(x):
    g = x.group()
    return "{"+g[1:]+"}" if int(x.group()[1:]) < len(args) else g

sub = re.sub(r"%\d+\b",f,  s).format(*args)

Или с помощью split и join, если заполнители всегда существуют самостоятельно:

print(" ".join(["{"+w[1:]+"}" if w[0] == "%" else w for w in s.split(" ")]).format(*args))

three and two and one 
5
Padraic Cunningham 14 Дек 2015 в 21:49

Используйте встроенное форматирование строки.

>>> print('%s is a %s %s' % ('Ram','good','boy'))
Ram is a good boy

Согласно вашему редактированию, вы ищете что-то другое. Вы можете использовать re.findall и re.sub для выполнения этого:

>>> import re
>>> formatstring,args = "%0 is a %1 %2",("Ram", "good", "boy")    
>>> for x in re.findall('(%\d+)',formatstring):
    formatstring = re.sub(x,args[int(x[1:])],formatstring)

>>> formatstring
'Ram is a good boy'
0
R Nar 14 Дек 2015 в 20:47

Может быть, использовать string.replace для замены различных %x их их аналогами кортежей, например:

format = "%0 is a %1 %2"
args = ("Ram", "good", "boy")

result = format  # Set it here in case args is the empty tuple

for index, arg in enumerate(args):
    formatter = '%' + str(index)  # "%0", "%1", etc
    result = result.replace(formatter, arg)

print(result)
0
RemcoGerlich 14 Дек 2015 в 20:36