TypeError:pythonの文字列フォーマット中にすべての引数が変換されるわけではありません


192

プログラムは2つの名前を取ることになっています。それらが同じ長さである場合、それらが同じ単語であるかどうかを確認する必要があります。同じ単語の場合は、「名前は同じです」と表示されます。長さが同じで文字が異なる場合は、「名前は異なりますが長さが同じです」と出力されます。私が問題を抱えている部分は、下の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 2016年

7
%より簡潔です。それが私たちと一緒にいるのはうれしいです。
Lenar Hoyt 2016

3
私は同意します。%はより簡潔であり、削除しても言語にメリットはありません。
chevydog 2017

@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

他の2つの答えに加えて、最後の2つの条件ではインデントも正しくないと思います。条件は、1つの名前が他の名前より長く、「elif」で始まり、インデントなしである必要があることです。(マージンから4つのインデントを与えることによって)最初の条件内に置くと、名前の長さを同時に等しくしたり、異なったりすることはできないため、矛盾します。

    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が指摘したように、さまざまな文字列フォーマット方法が混在しています。
  2. GuyPが指摘したように、インデントもオフになっています。

.formatの例と、%sの引数指定子にタプルを渡すことの両方を提供しました。どちらの場合も、インデントは修正されているため、長さが一致する場合、チェックの範囲外または範囲外になります。また、後続のifステートメントをelifに変更したため、前の同じレベルのステートメントがFalseの場合にのみ実行されます。

.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

私にとっては、1回の印刷呼び出しで多くの値を格納していたため、解決策は、データをタプルとして格納する別の変数を作成してから、印刷関数を呼び出すことでした。

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

0

エラーも発生します

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

しかし、リスト引数はうまく機能します。

mysqlclient python libを使用しています。libはタプル引数を受け入れないように見えます。リスト引数を渡すよう['arg1', 'arg2'] に動作します。


0

ビューのdjango raw sqlクエリ

"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を使用

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.