TypeError: nie wszystkie argumenty skonwertowane podczas python formatowania łańcucha

192

Program powinien przyjmować dwie nazwy, a jeśli mają taką samą długość, powinien sprawdzić, czy są to to samo słowo. Jeśli jest to to samo słowo, zostanie wydrukowane „Nazwy są takie same” . Jeśli mają taką samą długość, ale mają różne litery, zostanie wydrukowany „Nazwy są różne, ale mają tę samą długość” . Część, z którą mam problem, to dolne 4 wiersze.

#!/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)

Po uruchomieniu tego kodu wyświetla się:

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

Wszelkie sugestie są bardzo mile widziane.

użytkownik2652300
źródło

Odpowiedzi:

210

Miksujesz różne funkcje formatowania.

%Formatowanie w starym stylu wykorzystuje %kody do formatowania:

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

{}Formatowanie w nowym stylu wykorzystuje {}kody i .formatmetodę

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

Zauważ, że przy formatowaniu w starym stylu musisz podać wiele argumentów za pomocą krotki:

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

W twoim przypadku, ponieważ używasz {}specyfikatorów formatu, użyj .format:

"'{0}' is longer than '{1}'".format(name1, name2)
nneonneo
źródło
17
w python 3.6:f"'It will cost ${your_variable} dollars."
JinSnow
51

Błąd dotyczy formatowania łańcucha.

Prawidłowym sposobem korzystania z tradycyjnego formatowania ciągów za pomocą operatora „%” jest użycie ciągu formatu formatu printf (dokumentacja Pythona w tym celu: http://docs.python.org/2/library/string.html#format- składnia łańcuchowa ):

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

Jednak operator „%” prawdopodobnie będzie przestarzały w przyszłości . Nowy sposób robienia rzeczy w PEP 3101 wygląda następująco:

"'{0}' is longer than '{1}'".format(name1, name2)
leonh
źródło
9
scnr: „prawdopodobnie będzie przestarzałe w przyszłości” jak dotąd nie miało miejsca (Python 3.5). Stara składnia „%” nie była przestarzała w wersji 3.1 i tylko w module logowania{} w wersji 3.2 nauczył się, jak formatować w nowym stylu . I nagle 3.5 wprowadza PEP 461: %formatowanie bajtów . To sprawia, że ​​myślę o %szczątkach jeszcze długo.
cfi
7
%jest bardziej zwięzły. Cieszę się, że zostaje z nami.
Lenar Hoyt,
3
Zgadzam się. % jest bardziej zwięzłe, a usunięcie nie przyniosłoby żadnych korzyści dla języka.
chevydog
@LenarHoyt Co sądzisz o f-stringach? Nie mogę sobie wyobrazić, że jest to "'%s' is longer than '%s'" % (name1, name2)bardziej zwięzłe niżf"'{name1}' is longer than '{name2}'"
Mark Moretto
44

Dla mnie ten błąd został spowodowany, gdy próbowałem przekazać krotkę do metody formatu ciągu.

Znalazłem rozwiązanie z tego pytania / odpowiedzi

Kopiowanie i wklejanie poprawnej odpowiedzi z linku (NIE MOJA PRACA) :

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

Kluczem jest tutaj wykonanie krotki singleton z krotką zainteresowania jako jedyną pozycją, tj. Częścią (thetuple).

Nick Brady
źródło
Wolałbym przekonwertować krotkę na ciąg za pomocą jednej z następujących instrukcji: print("this is a tuple: %s" % str(thetuple))lubprint("this is a tuple: %s" % repr(thetuple))
AlexG
12

W moim przypadku to dlatego, że potrzebuję tylko jednego %s, brakuje wartości wejściowych.

ParisNakitaKejser
źródło
@ParisNakitaKejser, więc jak uzyskać parametr wejściowy dla pojedynczego% s?
Jatin Patel - JP
6

Oprócz dwóch pozostałych odpowiedzi, myślę, że wcięcia są również niepoprawne w dwóch ostatnich warunkach. Warunki są takie, że jedno imię jest dłuższe od drugiego i muszą zaczynać się od „elif” i bez wcięć. Jeśli umieścisz go w pierwszym warunku (podając cztery wcięcia od marginesu), skończy się to sprzecznością, ponieważ długości nazw nie mogą być równe i różne w tym samym czasie.

    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
źródło
3

Istnieje kilka problemów wskazanych w kilku innych odpowiedziach.

  1. Jak zauważył nneonneo, miksujesz różne metody formatowania łańcucha.
  2. Jak wskazał GuyP, twoje wcięcie również jest wyłączone.

Podałem zarówno przykład .format, jak i przekazywanie krotek do specyfikatora argumentu% s. W obu przypadkach wcięcie zostało naprawione, więc większe / mniejsze niż kontrole są poza momentem dopasowania długości. Zmieniono również kolejne instrukcje if na elif, więc działają tylko wtedy, gdy poprzednia instrukcja tego samego poziomu była fałszywa.

Formatowanie ciągów za pomocą .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))

Formatowanie ciągów za pomocą% si krotki

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))
Trevor Benson
źródło
2

W Pythonie 3.7 i nowszych istnieje nowy i łatwy sposób. oto składnia:

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

Wynik:

Hello, Eric. You are 74.
Shani
źródło
1

Dla mnie, ponieważ przechowywałem wiele wartości w jednym wywołaniu drukowania, rozwiązaniem było utworzenie osobnej zmiennej do przechowywania danych jako krotki, a następnie wywołanie funkcji drukowania.

x = (f"{id}", f"{name}", f"{age}")
print(x) 
Neel0507
źródło
0

Wystąpił również błąd,

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

Ale lista argumentów działa dobrze.

Używam mysqlclient python lib. Wygląda na to, że lib nie akceptuje krotek argumentów. Aby przekazać listę, argumenty jak ['arg1', 'arg2'] będą działać.

Victor Choy
źródło
0

zapytanie django raw sql w widoku

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

Uwaga: używając Pythona 3.5 i django 1.11

Vinay Kumar
źródło