TypeError: non tutti gli argomenti convertiti durante la formattazione delle stringhe in Python


192

Il programma dovrebbe assumere due nomi e, se hanno la stessa lunghezza, dovrebbe verificare se sono la stessa parola. Se è la stessa parola, verrà stampato "I nomi sono gli stessi" . Se hanno la stessa lunghezza ma con lettere diverse, verrà stampato "I nomi sono diversi ma la stessa lunghezza" . La parte con cui sto avendo problemi è nelle 4 righe in basso.

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

Quando eseguo questo codice viene visualizzato:

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

Eventuali suggerimenti sono molto apprezzati.

Risposte:


210

Stai mescolando diverse funzioni di formato.

La %formattazione vecchio stile utilizza %codici per la formattazione:

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

La {}formattazione di nuovo stile utilizza i {}codici e il .formatmetodo

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

Nota che con la formattazione vecchio stile, devi specificare più argomenti usando una tupla:

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

Nel tuo caso, poiché stai utilizzando gli {}identificatori di formato, usa .format:

"'{0}' is longer than '{1}'".format(name1, name2)

17
in python 3.6:f"'It will cost ${your_variable} dollars."
JinSnow il

51

L'errore è nella formattazione della stringa.

Il modo corretto di utilizzare la formattazione di stringa tradizionale utilizzando l'operatore '%' è utilizzare una stringa di formato in stile printf (documentazione Python per questo qui: http://docs.python.org/2/library/string.html#format- sintassi stringa ):

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

Tuttavia, l'operatore '%' sarà probabilmente deprecato in futuro . Il nuovo modo di fare PEP 3101 è così:

"'{0}' is longer than '{1}'".format(name1, name2)

9
scnr: "probabilmente sarà deprecato in futuro" non è successo finora (Python 3.5). La vecchia sintassi '%' non era obsoleta in 3.1 e solo nel modulo di registrazione{} 3.2 ha imparato a formattare con il nuovo stile . E improvvisamente 3.5 porta PEP 461: %formattazione per byte . Questo mi fa pensare ai %resti per molto tempo a venire.
cfi,

7
%è più conciso. Sono contento che rimanga con noi.
Lenar Hoyt,

3
Concordo. % è più conciso e la rimozione non aggiungerebbe alcun vantaggio alla lingua.
Chevydog,

@LenarHoyt Come ti senti con le f-stringhe? Non riesco a immaginare che sia "'%s' is longer than '%s'" % (name1, name2)più conciso dif"'{name1}' is longer than '{name2}'"
Mark Moretto il

44

Per me, questo errore è stato causato quando stavo tentando di passare una tupla nel metodo del formato stringa.

Ho trovato la soluzione da questa domanda / risposta

Copia e incolla della risposta corretta dal link (NON IL MIO LAVORO) :

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

Fare una tupla singleton con la tupla di interesse come unico elemento, ovvero la parte (thetuple,), è il bit chiave qui.


Preferirei convertire la tupla in una stringa usando una delle seguenti affermazioni: print("this is a tuple: %s" % str(thetuple))oppureprint("this is a tuple: %s" % repr(thetuple))
AlexG

12

Nel mio caso, è perché ho bisogno solo di un singolo %sinput di valori mancanti.


@ParisNakitaKejser, quindi come ottenere i parametri di input per il singolo% s?
Jatin Patel - JP

6

Oltre alle altre due risposte, penso che i rientri siano errati anche nelle ultime due condizioni. Le condizioni sono che un nome sia più lungo dell'altro e devono iniziare con 'elif' e senza rientri. Se lo metti nella prima condizione (dandogli quattro rientranze dal margine), finisce per essere contraddittorio perché le lunghezze dei nomi non possono essere uguali e diverse allo stesso tempo.

    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

C'è una combinazione di problemi, come sottolineato in alcune delle altre risposte.

  1. Come sottolineato da nneonneo, state mescolando diversi metodi di formattazione delle stringhe.
  2. Come sottolineato da GuyP anche il tuo rientro è disattivato.

Ho fornito sia l'esempio di .format sia il passaggio di tuple allo specificatore di argomenti di% s. In entrambi i casi il rientro è stato corretto in modo tale che maggiore / minore dei controlli non coincidano con la corrispondenza della lunghezza. Inoltre cambiarono le successive istruzioni if ​​in elif's in modo che vengano eseguite solo se la precedente istruzione dello stesso livello era False.

Formattazione di stringhe con .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))

Formattazione di stringhe con% se tupla

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

In Python 3.7 e versioni successive c'è un modo nuovo e semplice. ecco la sintassi:

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

Produzione:

Hello, Eric. You are 74.

1

Per me, poiché stavo memorizzando molti valori in una singola chiamata di stampa, la soluzione era creare una variabile separata per archiviare i dati come tupla e quindi chiamare la funzione di stampa.

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

0

Riscontro anche l'errore,

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

Ma gli argomenti della lista funzionano bene.

Uso mysqlclient python lib. La lib sembra non accettare arg tuple. Per passare alla lista argomenti come ['arg1', 'arg2'] funzionerà.


0

query sql raw django in vista

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

Nota: usando python 3.5 e django 1.11

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.