TypeError: Nicht alle Argumente wurden während der Python-Formatierung von Zeichenfolgen konvertiert

192

Das Programm soll zwei Namen annehmen, und wenn sie die gleiche Länge haben, sollte es prüfen, ob sie das gleiche Wort sind. Wenn es das gleiche Wort ist, wird "Die Namen sind die gleichen" gedruckt . Wenn sie gleich lang sind, aber unterschiedliche Buchstaben haben, wird "Die Namen sind unterschiedlich, aber gleich lang" ausgegeben . Der Teil, mit dem ich ein Problem habe, befindet sich in den unteren 4 Zeilen.

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

Wenn ich diesen Code ausführe, wird Folgendes angezeigt:

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

Anregungen werden sehr geschätzt.

user2652300
quelle

Antworten:

210

Sie mischen verschiedene Formatfunktionen.

Bei der %Formatierung im alten Stil werden %Codes für die Formatierung verwendet:

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

Die {}Formatierung im neuen Stil verwendet {}Codes und die .formatMethode

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

Beachten Sie, dass Sie bei der Formatierung im alten Stil mehrere Argumente mit einem Tupel angeben müssen:

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

Verwenden Sie in Ihrem Fall Folgendes, da Sie Formatspezifizierer {}verwenden .format:

"'{0}' is longer than '{1}'".format(name1, name2)
nneonneo
quelle
17
in Python 3.6:f"'It will cost ${your_variable} dollars."
JinSnow
51

Der Fehler liegt in Ihrer Zeichenfolgenformatierung.

Die korrekte Verwendung der herkömmlichen Zeichenfolgenformatierung mit dem Operator '%' ist die Verwendung einer Zeichenfolge im Printf-Format (Python-Dokumentation hierzu hier: http://docs.python.org/2/library/string.html#format- String-Syntax ):

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

Der Operator '%' wird jedoch wahrscheinlich in Zukunft veraltet sein . Die neue Vorgehensweise nach PEP 3101 sieht folgendermaßen aus:

"'{0}' is longer than '{1}'".format(name1, name2)
leonh
quelle
9
scnr: "wird wahrscheinlich in Zukunft veraltet sein" ist bisher nicht geschehen (Python 3.5). Die alte '%'-Syntax war in 3.1 nicht veraltet und nur im 3.2- Protokollierungsmodul wurde das Formatieren mit dem neuen Stil erlernt{} . Und plötzlich bringt 3.5 PEP 461: %Formatierung für Bytes . Das lässt mich denken, dass die %Überreste noch lange auf sich warten lassen.
cfi
7
%ist prägnanter. Ich bin froh, dass es bei uns bleibt.
Lenar Hoyt
3
Ich stimme zu. % ist prägnanter und das Entfernen würde der Sprache keinen Nutzen bringen.
Chevydog
@LenarHoyt Wie denkst du über F-Strings? Ich kann mir nicht vorstellen, dass das "'%s' is longer than '%s'" % (name1, name2)prägnanter ist alsf"'{name1}' is longer than '{name2}'"
Mark Moretto
44

Für mich wurde dieser Fehler verursacht, als ich versuchte, ein Tupel an die String-Format-Methode zu übergeben.

Ich habe die Lösung aus dieser Frage / Antwort gefunden

Kopieren und Einfügen der richtigen Antwort aus dem Link (NICHT MEINE ARBEIT) :

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

Das Erstellen eines Singleton-Tupels mit dem interessierenden Tupel als einzigem Element, dh dem (Thetupel-) Teil, ist hier das Schlüsselbit.

Nick Brady
quelle
Ich würde das Tupel lieber mit einer der folgenden Anweisungen in einen String konvertieren: print("this is a tuple: %s" % str(thetuple))oderprint("this is a tuple: %s" % repr(thetuple))
AlexG
12

In meinem Fall liegt es daran, dass ich nur eine einzige %sEingabe für fehlende Werte benötige .

ParisNakitaKejser
quelle
@ParisNakitaKejser, wie bekomme ich Eingabeparameter für einzelne% s?
Jatin Patel - JP
6

Zusätzlich zu den beiden anderen Antworten denke ich, dass die Einrückungen auch in den letzten beiden Bedingungen falsch sind. Die Bedingungen sind, dass ein Name länger als der andere ist und sie mit 'elif' und ohne Einrückungen beginnen müssen. Wenn Sie es in die erste Bedingung einfügen (indem Sie ihm vier Einrückungen vom Rand geben), wird es widersprüchlich, da die Länge der Namen nicht gleichzeitig gleich und unterschiedlich sein kann.

    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
quelle
3

Es gibt eine Kombination von Problemen, auf die in einigen anderen Antworten hingewiesen wird.

  1. Wie von nneonneo hervorgehoben, mischen Sie verschiedene Methoden zur Zeichenfolgenformatierung.
  2. Wie von GuyP hervorgehoben, ist auch Ihre Einrückung deaktiviert.

Ich habe sowohl das Beispiel für .format als auch die Übergabe von Tupeln an den Argumentspezifizierer von% s angegeben. In beiden Fällen wurde die Einrückung so korrigiert, dass sie größer / kleiner als die Überprüfungen sind, wenn die Länge übereinstimmt. Außerdem wurden nachfolgende if-Anweisungen in elif geändert, sodass sie nur ausgeführt werden, wenn die vorherige Anweisung auf derselben Ebene False war.

String-Formatierung mit .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))

String-Formatierung mit% s und einem Tupel

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
quelle
2

In Python 3.7 und höher gibt es einen neuen und einfachen Weg. Hier ist die Syntax:

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

Ausgabe:

Hello, Eric. You are 74.
Shani
quelle
1

Da ich viele Werte in einem einzigen Druckaufruf gespeichert habe, bestand die Lösung darin, eine separate Variable zu erstellen, um die Daten als Tupel zu speichern und dann die Druckfunktion aufzurufen.

x = (f"{id}", f"{name}", f"{age}")
print(x) 
Neel0507
quelle
0

Ich stoße auch auf den Fehler,

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

Aber Listenargumente funktionieren gut.

Ich benutze mysqlclient python lib. Die Bibliothek scheint keine Tupelargumente zu akzeptieren. Das Übergeben von Listenargumenten ['arg1', 'arg2'] funktioniert.

Victor Choy
quelle
0

Django Raw SQL-Abfrage in Ansicht

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

Hinweis: Verwenden von Python 3.5 und Django 1.11

Vinay Kumar
quelle