TypeError: не всі аргументи, перетворені під час форматування рядка 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

Будь-які пропозиції високо оцінені.

Відповіді:


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)

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)

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


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))

3

Існує поєднання питань, на які вказувалося в кількох інших відповідях.

  1. Як зазначає nneonneo, ви змішуєте різні методи String Formatting.
  2. Як вказує GuyP, ваш відступ також вимкнено.

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

Форматування рядків за допомогою .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) 

0

Я також стикаюся з помилкою,

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

Але аргументи списку працюють добре.

Я використовую mysqlclient python lib. Біль схожа на те, що не сприймає кортежі. Для передачі списку такі аргументи ['arg1', 'arg2'] працюватимуть.


0

django raw sql query in view

"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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.