TypeError: nem todos os argumentos são convertidos durante o python de formatação de string

192

O programa deve incluir dois nomes e, se tiverem o mesmo tamanho, deve verificar se têm a mesma palavra. Se for a mesma palavra, será exibido "Os nomes são os mesmos" . Se tiverem o mesmo comprimento, mas com letras diferentes, será impresso "Os nomes são diferentes, mas com o mesmo comprimento" . A parte com a qual estou tendo problemas está nas quatro linhas inferiores.

#!/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 executo esse código, ele exibe:

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

Todas as sugestões são muito apreciadas.

user2652300
fonte

Respostas:

210

Você está misturando diferentes funções de formato.

A %formatação à moda antiga usa %códigos para formatação:

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

A {}formatação de novo estilo usa {}códigos e o .formatmétodo

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

Observe que, com a formatação de estilo antigo, você deve especificar vários argumentos usando uma tupla:

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

No seu caso, como você está usando {}especificadores de formato, use .format:

"'{0}' is longer than '{1}'".format(name1, name2)
nneonneo
fonte
17
em python 3.6:f"'It will cost ${your_variable} dollars."
JinSnow 22/03
51

O erro está na sua formatação de string.

A maneira correta de usar a formatação de string tradicional usando o operador '%' é usar uma string de formato no estilo printf (documentação em Python para isso aqui: http://docs.python.org/2/library/string.html#format- sintaxe da string ):

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

No entanto, o operador '%' provavelmente será preterido no futuro . A nova maneira de fazer as coisas PEP 3101 é assim:

"'{0}' is longer than '{1}'".format(name1, name2)
leonh
fonte
9
scnr: "provavelmente será reprovado no futuro" não aconteceu até o momento (Python 3.5). A sintaxe '%' antiga não foi preterida no 3.1 e somente no módulo de registro{} 3.2 aprendeu como formatar com o novo estilo . E de repente 3.5 traz o PEP 461: %formatação para bytes . Isso me faz pensar nos %restos por muito tempo.
Cfi 07/01
7
%é mais conciso. Ainda bem que fica conosco.
Lenar Hoyt
3
Eu concordo. % é mais conciso e a remoção não traria benefícios ao idioma.
chevydog
@LenarHoyt Como você se sente com as f-strings? Eu não posso imaginar que é "'%s' is longer than '%s'" % (name1, name2)mais conciso do quef"'{name1}' is longer than '{name2}'"
Mark Moretto
44

Para mim, esse erro foi causado quando eu estava tentando passar uma tupla para o método de formato de string.

Encontrei a solução desta pergunta / resposta

Copiando e colando a resposta correta do link (NÃO MEU TRABALHO) :

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

Fazer uma tupla simples com a tupla de interesse como o único item, ou seja, a parte (thuple,) é a parte principal aqui.

Nick Brady
fonte
Eu prefiro converter o tuple para uma cadeia utilizando uma das seguintes afirmações: print("this is a tuple: %s" % str(thetuple))ouprint("this is a tuple: %s" % repr(thetuple))
AlexG
12

No meu caso, é porque eu preciso apenas de uma única %sentrada de valores ausentes.

ParisNakitaKejser
fonte
@ParisNakitaKejser, então como obter parâmetros de entrada para o único% s?
Jatin Patel - JP
6

Além das outras duas respostas, acho que os recuos também estão incorretos nas duas últimas condições. As condições são que um nome seja mais longo que o outro e eles precisam começar com 'elif' e sem recuos. Se você colocá-lo na primeira condição (dando quatro recuos na margem), isso acaba sendo contraditório, pois os comprimentos dos nomes não podem ser iguais e diferentes ao mesmo 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))
GuyP
fonte
3

Há uma combinação de problemas, conforme apontado em algumas das outras respostas.

  1. Conforme indicado por nneonneo, você está misturando diferentes métodos de formatação de string.
  2. Como apontado pelo GuyP, seu recuo também está desligado.

Forneci o exemplo de .format e também a transmissão de tuplas para o especificador de argumento de% s. Nos dois casos, o recuo foi corrigido de forma que seja maior / menor que as verificações externas quando o comprimento corresponder. Também foram alteradas as instruções if subsequentes para elif, para que sejam executadas apenas se a instrução anterior no mesmo nível for False.

Formatação de seqüência de caracteres com .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))

Formatação de string com% se uma 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))
Trevor Benson
fonte
2

No python 3.7 e acima, há uma maneira nova e fácil. aqui está a sintaxe:

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

Resultado:

Hello, Eric. You are 74.
Shani
fonte
1

Para mim, como eu estava armazenando muitos valores em uma única chamada de impressão, a solução foi criar uma variável separada para armazenar os dados como uma tupla e depois chamar a função de impressão.

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

Eu também encontro o erro,

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

Mas argumentos de lista funcionam bem.

Eu uso o mysqlclient python lib. A lib parece não aceitar argumentos de tupla. Para passar a lista args como ['arg1', 'arg2'] irá funcionar.

Victor Choy
fonte
0

consulta sql raw do django na exibição

"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

Vinay Kumar
fonte