Ошибка типа: не все аргументы, преобразованные во время форматирования строки Python

192

Предполагается, что программа принимает два имени, и если они имеют одинаковую длину, она должна проверить, являются ли они одним словом. Если это одно и то же слово, будет напечатано «Имена одинаковые» . Если они имеют одинаковую длину, но с разными буквами, будет напечатано «Имена разные, но одинаковой длины» . Часть, с которой у меня проблема, находится в нижних 4 строках.

#!/usr/bin/env python
# Enter your code for "What's In (The Length Of) A Name?" here.
name1 = input("Enter name 1: ")
name2 = input("Enter name 2: ")
len(name1)
len(name2)
if len(name1) == len(name2):
    if name1 == name2:
        print ("The names are the same")
    else:
        print ("The names are different, but are the same length")
    if len(name1) > len(name2):
        print ("'{0}' is longer than '{1}'"% name1, name2)
    elif len(name1) < len(name2):
        print ("'{0}'is longer than '{1}'"% name2, name1)

Когда я запускаю этот код, он отображает:

Traceback (most recent call last):
  File "program.py", line 13, in <module>
    print ("'{0}' is longer than '{1}'"% name1, name2)
TypeError: not all arguments converted during string formatting

Любые предложения высоко ценятся.

user2652300
источник

Ответы:

210

Вы смешиваете разные функции формата.

%Форматирование старого стиля использует %коды для форматирования:

'It will cost $%d dollars.' % 95

{}Форматирование нового стиля использует {}коды и .formatметод

'It will cost ${0} dollars.'.format(95)

Обратите внимание, что при форматировании в старом стиле вы должны указать несколько аргументов, используя кортеж:

'%d days and %d nights' % (40, 40)

В вашем случае, так как вы используете {}спецификаторы формата, используйте .format:

"'{0}' is longer than '{1}'".format(name1, name2)
nneonneo
источник
17
в Python 3.6:f"'It will cost ${your_variable} dollars."
JinSnow
51

Ошибка в форматировании вашей строки.

Правильный способ использовать традиционное форматирование строки с использованием оператора «%» - это использовать строку формата в стиле printf (документация Python для этого здесь: http://docs.python.org/2/library/string.html#format- строковый синтаксис ):

"'%s' is longer than '%s'" % (name1, name2)

Тем не менее, оператор '%' , вероятно, будет исключен в будущем . Новый способ PEP 3101 заключается в следующем:

"'{0}' is longer than '{1}'".format(name1, name2)
leonh
источник
9
scnr: «вероятно, не рекомендуется в будущем» до сих пор не произошло (Python 3.5). Старый синтаксис «%» не был объявлен устаревшим в 3.1, и только в модуле ведения журнала{} 3.2 он научился форматировать в новом стиле . И вдруг 3.5 приносит PEP 461: %форматирование для байтов . Это заставляет меня думать, что %останки надолго.
Cfi
7
%является более кратким. Рад, что это остается с нами.
Ленар Хойт
3
Я согласен. % более лаконичен, и удаление не добавит никакой пользы языку.
chevydog
@LenarHoyt Как вы относитесь к f-струнам? Я не могу представить, что это "'%s' is longer than '%s'" % (name1, name2)более кратко, чемf"'{name1}' is longer than '{name2}'"
Марк Моретто
44

Для меня эта ошибка была вызвана, когда я пытался передать кортеж в метод строкового формата.

Я нашел решение из этого вопроса / ответа

Копирование и вставка правильного ответа по ссылке (НЕ МОЯ РАБОТА) :

>>> thetuple = (1, 2, 3)
>>> print "this is a tuple: %s" % (thetuple,)
this is a tuple: (1, 2, 3)

Создание одноэлементного кортежа с интересующим кортежем в качестве единственного элемента, то есть части (thetuple,), является ключевым битом здесь.

Ник Брэйди
источник
Я бы лучше преобразовал кортеж в строку, используя одно из следующих утверждений: print("this is a tuple: %s" % str(thetuple))илиprint("this is a tuple: %s" % repr(thetuple))
AlexG
12

В моем случае это потому, что мне нужен только один %s, я пропускаю значения ввода.

ParisNakitaKejser
источник
@ParisNakitaKejser, как получить входной параметр для одного% s?
Джатин Патель - JP
6

В дополнение к двум другим ответам, я думаю, что отступы также неверны в двух последних условиях. Условия состоят в том, что одно имя длиннее другого, и они должны начинаться с «elif» и без отступов. Если вы поместите его в первое условие (указав четыре отступа от поля), оно окажется противоречивым, потому что длины имен не могут быть одинаковыми и разными в одно и то же время.

    else:
        print ("The names are different, but are the same length")
elif len(name1) > len(name2):
    print ("{0} is longer than {1}".format(name1, name2))
GuyP
источник
3

Существует несколько вопросов, как указано в нескольких других ответах.

  1. Как указывает nneonneo, вы смешиваете разные методы форматирования строк.
  2. Как отмечает GuyP, ваши отступы также отключены.

Я предоставил как пример .format, так и передачу кортежей в спецификатор аргумента% s. В обоих случаях отступ был исправлен, поэтому проверки больше, чем когда длина совпадает. Также изменил последующие операторы if на elif, чтобы они выполнялись, только если предыдущий оператор того же уровня был False.

Форматирование строк с помощью .format

name1 = input("Enter name 1: ")
name2 = input("Enter name 2: ")
len(name1)
len(name2)
if len(name1) == len(name2):
    if name1 == name2:
        print ("The names are the same")
    else:
        print ("The names are different, but are the same length")
elif len(name1) > len(name2):
    print ("{0} is longer than {1}".format(name1, name2))
elif len(name1) < len(name2):
    print ("{0} is longer than {1}".format(name2, name1))

Форматирование строки с% s и кортежем

name1 = input("Enter name 1: ")
name2 = input("Enter name 2: ")
len(name1)
len(name2)
if len(name1) == len(name2):
    if name1 == name2:
        print ("The names are the same")
    else:
        print ("The names are different, but are the same length")
elif len(name1) > len(name2):
    print ("%s is longer than %s" % (name1, name2))
elif len(name1) < len(name2):
    print ("%s is longer than %s" % (name2, name1))
Тревор Бенсон
источник
2

В Python 3.7 и выше есть новый и простой способ. вот синтаксис:

name = "Eric"
age = 74
f"Hello, {name}. You are {age}."

Вывод:

Hello, Eric. You are 74.
Шани
источник
1

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

x = (f"{id}", f"{name}", f"{age}")
print(x) 
Neel0507
источник
0

Я также сталкиваюсь с ошибкой,

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

Но список аргументов работает хорошо.

Я использую mysqlclient python lib. Похоже, что lib не принимает аргументы кортежа. Передать список аргументов вроде ['arg1', 'arg2'] будет работать.

Виктор Чой
источник
0

django raw sql запрос в поле зрения

"SELECT * FROM VendorReport_vehicledamage WHERE requestdate BETWEEN '{0}' AND '{1}'".format(date_from, date_to)

models.py

class VehicleDamage(models.Model):
    requestdate = models.DateTimeField("requestdate")
    vendor_name = models.CharField("vendor_name", max_length=50)
    class Meta:
        managed=False

views.py

def location_damageReports(request):
    #static date for testing
    date_from = '2019-11-01'
    date_to = '2019-21-01'
    vehicle_damage_reports = VehicleDamage.objects.raw("SELECT * FROM VendorReport_vehicledamage WHERE requestdate BETWEEN '{0}' AND '{1}'".format(date_from, date_to))
    damage_report = DashboardDamageReportSerializer(vehicle_damage_reports, many=True)
    data={"data": damage_report.data}
    return HttpResponse(json.dumps(data), content_type="application/json")

Примечание: использование python 3.5 и django 1.11

Винай Кумар
источник