文字列のフォーマット:%と.format


1349

Python 2.6では、str.format()既存の%演算子とは構文が少し異なるメソッドが導入されました。どちらがより適切で、どのような状況に適していますか?

  1. 以下はそれぞれの方法を使用し、同じ結果をもたらすので、違いは何ですか?

    #!/usr/bin/python
    sub1 = "python string!"
    sub2 = "an arg"
    
    a = "i am a %s" % sub1
    b = "i am a {0}".format(sub1)
    
    c = "with %(kwarg)s!" % {'kwarg':sub2}
    d = "with {kwarg}!".format(kwarg=sub2)
    
    print a    # "i am a python string!"
    print b    # "i am a python string!"
    print c    # "with an arg!"
    print d    # "with an arg!"
    
  2. さらに、Pythonでは文字列フォーマットがいつ発生しますか?たとえば、ロギングレベルがHIGHに設定されている場合でも、次の%操作を実行するためにヒットしますか?もしそうなら、これを回避する方法はありますか?

    log.debug("some debug info: %s" % some_info)


2
初心者向け:ここに両方のスタイルを教える非常に素晴らしいチュートリアルがあります。個人的には、古い%スタイルをより頻繁に使用しています。スタイルの改善された機能が必要ない場合は、format()スタイルの%方がはるかに便利です。
Lutz Prechelt



1
2番目の質問に答えるには、3.2以降、カスタムフォーマッターを使用している場合は{}形式を使用できます(docs.python.org/3/library/logging.html#logging.Formatterを参照)
yanjost

回答:


953

最初の質問に答えるに.formatは、多くの点でより洗練されているように見えます。厄介なの%は、変数またはタプルを取得する方法でもあります。あなたは次のことが常にうまくいくと思います:

"hi there %s" % name

まだ、nameたまたまの場合(1, 2, 3)、がスローされますTypeError。それが常に印刷されることを保証するには、あなたがする必要があります

"hi there %s" % (name,)   # supply the single argument as a single-item tuple

これは醜いです。.formatこれらの問題はありません。また、2番目の例では、.format見た目がよりすっきりしています。

なぜそれを使わないのですか?

  • それについて知らない(これを読む前の私)
  • Python 2.5との互換性が必要

2番目の質問に答えるために、文字列フォーマットは、他の操作と同時に(文字列フォーマット式が評価されるときに)発生します。そして、怠惰な言語ではないPythonは、関数を呼び出す前に式を評価するので、log.debug例では、式"some debug info: %s"%some_infoは最初に評価されます。たとえば"some debug info: roflcopters are active"、その文字列はに渡されlog.debug()ます。


113
どう"%(a)s, %(a)s" % {'a':'test'}
ですか

128
以下のためにあなたが時間を無駄にすることに注意してくださいlog.debug("something: %s" % x)が、ためではないlog.debug("something: %s", x) 文字列フォーマット方法で処理され、それがログに記録されません場合は、パフォーマンスヒットを取得することはありません。いつものように、Pythonはお客様のニーズを予測します=)
darkfeline

63
ted:これはと同じことをするのは見た目が悪いハック'{0}, {0}'.format('test')です。
空飛ぶ羊

19
重要な点は、新しい構文でアイテムの並べ替えが可能になるという繰り返しの引数の1つは問題点です。古い構文でも同じことができます。ほとんどの人は、これが実際にAnsi C99 Stdですでに定義されていることを知りません。の最新のコピーをチェックして、プレースホルダー内man sprintf$表記について学ぶ%
cfi

29
@cfi:printf("%2$d", 1, 3)"3"を出力するような意味の場合、それはC99ではなくPOSIXで指定されています。あなたが参照したまさにそのマニュアルページは、「C99標準は '$'を使用するスタイルを含みません…」
タナトス2013年

307

モジュロ演算子(%)が実行できないこと、afaik:

tu = (12,45,22222,103,6)
print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)

結果

12 22222 45 22222 103 22222 6 22222

非常に便利。

別の点:format()関数であるは、他の関数の引数として使用できます。

li = [12,45,78,784,2,69,1254,4785,984]
print map('the number is {}'.format,li)   

print

from datetime import datetime,timedelta

once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0)
delta = timedelta(days=13, hours=8,  minutes=20)

gen =(once_upon_a_time +x*delta for x in xrange(20))

print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))

結果:

['the number is 12', 'the number is 45', 'the number is 78', 'the number is 784', 'the number is 2', 'the number is 69', 'the number is 1254', 'the number is 4785', 'the number is 984']

2010-07-01 12:00:00
2010-07-14 20:20:00
2010-07-28 04:40:00
2010-08-10 13:00:00
2010-08-23 21:20:00
2010-09-06 05:40:00
2010-09-19 14:00:00
2010-10-02 22:20:00
2010-10-16 06:40:00
2010-10-29 15:00:00
2010-11-11 23:20:00
2010-11-25 07:40:00
2010-12-08 16:00:00
2010-12-22 00:20:00
2011-01-04 08:40:00
2011-01-17 17:00:00
2011-01-31 01:20:00
2011-02-13 09:40:00
2011-02-26 18:00:00
2011-03-12 02:20:00

17
古いスタイルのフォーマットをフォーマットとmap同じくらい簡単に使用できます。map('some_format_string_%s'.__mod__, some_iterable)
agf

3
@cfi:C99で上記の例を書き直して、正しいことを証明してください
MarcH

9
@MarcH:でprintf("%2$s %1$s\n", "One", "Two");コンパイルするgcc -std=c99 test.c -o testと、出力はになりTwo Oneます。しかし、私は正直に言います。それは、実際には C ではなくPOSIX拡張機能です。C/ C ++標準では、見たと思っていた場所で再び見つけることはできません。コードは 'c90' stdフラグでも機能します。sprintfマニュアルページこれにはリストされていませんが、libsがスーパーセットを実装できるようにしています。私のオリジナルの引数は、置き換え、まだ有効であるCPosix
CFI

8
ここでの最初のコメントは、この回答には適用されません。私はその言い回しを後悔している。Pythonでは、%プレースホルダーの並べ替えにモジュロ演算子を使用できません。ここではコメントの一貫性を保つために、最初のコメントは削除しないでください。ここで怒りを晴らしてしまったことをお詫びします。古い構文自体はこれを許可しないと頻繁に行われるステートメントに対して指示されます。完全に新しい構文を作成する代わりに、標準のPosix拡張機能を導入することもできます。私たちは両方を持つことができます。
cfi 2014

17
「モジュロ」は、除算後の剰余を評価する演算子を指します。この場合、パーセント記号はモジュロ演算子ではありません。
タコ

148

Pythonのloggingモジュールを使用し.debug()ている場合、自分でフォーマットを行うのではなく、文字列フォーマット引数を引数としてメソッドに渡すことができます。

log.debug("some debug info: %s", some_info)

ロガーが実際に何かをログに記録しない限り、フォーマットを回避します。


10
これは、今学んだばかりの役立つ情報です。それはメインの質問とは別に見えるので、それはそれ自体の質問がないのは残念です。同情OPは彼の質問を2つの別々の質問に分けませんでした。
12

12
次のようなdict形式を使用できます。log.debug("some debug info: %(this)s and %(that)s", dict(this='Tom', that='Jerry')) ただし、残念なことに .format()、Python 3.3でも新しいスタイル構文を使用することはできません。
Cito 2012年


26
これの主な利点はパフォーマンスではありません(文字列補間を実行すると、ログからの出力を使用して何をしている場合よりも速くなります(例:端末に表示、ディスクに保存)。ロギングアグリゲーターがある場合、 「すべてのsome_info」値があったとしても、「このエラーメッセージのインスタンスが12個あります」と伝えることができます。文字列をlog.debugに渡す前に文字列のフォーマットが行われる場合、これは不可能です。アグリゲータは「12の異なるログメッセージがありました」としか言えません
Jonathan Hartley

7
パフォーマンスが気になる場合は、dict()クラスのインスタンス化ではなく、リテラルのdict {}構文を使用してください。doughellmann.com
2012/

119

Python 3.6(2016)以降では、f文字列を使用して変数を置き換えることができます。

>>> origin = "London"
>>> destination = "Paris"
>>> f"from {origin} to {destination}"
'from London to Paris'

f"接頭辞に注意してください。Python 3.5以前でこれを試すと、を取得しSyntaxErrorます。

https://docs.python.org/3.6/reference/lexical_analysis.html#f-stringsを参照してください


1
これは質問の答えにはなりません。f-stringsについて言及している別の回答は、少なくともパフォーマンスについて語っています:stackoverflow.com/a/51167833/7851470
Georgy

60

PEP 3101は、%演算子をPython 3の新しい高度な文字列フォーマットに置き換えることを提案しています。


14
正しくない:「既存のメカニズムをそのままにしておくことで、下位互換性を維持できます。」; もちろん、文字列フォーマットを置き換え.formatません。 %
トビアス2013年

12
いいえ、BrainStormsの仮定は真です:「既存の '%'の代替として意図されています」。トバイアスの引用は、両方のシステムがしばらくの間共存することを意味します。RTFPEP
phobie

54

すべてを交換しようとしたときしかし、注意してください、ちょうど今、私は1つの問題を発見した%.format、既存のコードで:'{}'.format(unicode_string)エンコードUNICODE_STRINGにしようとすると、おそらく失敗します。

次のPythonインタラクティブセッションログをご覧ください。

Python 2.7.2 (default, Aug 27 2012, 19:52:55) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
; s='й'
; u=u'й'
; s
'\xd0\xb9'
; u
u'\u0439'

s単なる文字列(Python3では「バイト配列」と呼ばれます)でuあり、Unicode文字列(Python3では「文字列」と呼ばれます)です。

; '%s' % s
'\xd0\xb9'
; '%s' % u
u'\u0439'

%演算子のパラメーターとしてUnicodeオブジェクトを指定すると、元の文字列がUnicodeでなくても、Unicode文字列が生成されます。

; '{}'.format(s)
'\xd0\xb9'
; '{}'.format(u)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u0439' in position 0: ordinal not in range(256)

しかし、.format関数は "UnicodeEncodeError"を発生させます:

; u'{}'.format(s)
u'\xd0\xb9'
; u'{}'.format(u)
u'\u0439'

また、元の文字列がUnicodeの場合にのみ、Unicode引数で正常に機能します。

; '{}'.format(u'i')
'i'

または、引数文字列を文字列に変換できる場合(いわゆる「バイト配列」)


12
新しいformatメソッドの追加機能が本当に必要でない限り、実際に機能するコードを変更する理由はありません...
Tobias

Tobias氏と完全に同意しますが、新しいバージョンのPythonにアップグレードするときに必要になる場合があります
wobmene

2
例えば?私の知る限り、それは必要とされたことはありません%文字列の補間がなくなる可能性があるとは考えていません。
Tobias 2013年

4
文字列の.format()関数は%よりも安全だと思います。多くの場合、私はこのような初心者のミスを参照してください"p1=%s p2=%d" % "abc", 2"p1=%s p2=%s" % (tuple_p1_p2,)。あなたはそれがコーダーのせいだと思うかもしれませんが、quicky-scriptieには見栄えがいいが、プロダクションコードには悪いのは、奇妙な誤った構文だと思います。
ウォブメネ2014年

3
しかし、私は.format()の構文は好きではない、私は古い良いと幸せになると思います%s%02dのような"p1=%s p2=%02d".format("abc", 2)。私はあなたがそれらをエスケープするためにあなたを必要とし{{}}、醜い私見に見える中括弧のフォーマットを発明し承認した人々のせいです。
ウォブメネ2014年

35

.format(回答には記載されていない)のもう1つの利点:オブジェクトのプロパティを使用できる

In [12]: class A(object):
   ....:     def __init__(self, x, y):
   ....:         self.x = x
   ....:         self.y = y
   ....:         

In [13]: a = A(2,3)

In [14]: 'x is {0.x}, y is {0.y}'.format(a)
Out[14]: 'x is 2, y is 3'

または、キーワード引数として:

In [15]: 'x is {a.x}, y is {a.y}'.format(a=a)
Out[15]: 'x is 2, y is 3'

これは%私の知る限りでは不可能です。


4
これは、同等のものと比較して、必要以上に読みにくく見えます'x is {0}, y is {1}'.format(a.x, a.y)a.x操作に非常にコストがかかる場合にのみ使用してください。
dtheodor 2015年

13
代わりに位置引数のキーワード引数を使用するために微調整して@dtheodor ... 'x is {a.x}, y is {a.y}'.format(a=a)。両方の例よりも読みやすい。
CivFan 2015

1
@CivFanまたは、複数のオブジェクトがある場合'x is {a.x}, y is {a.y}'.format(**vars())
Jack

1
これも同じ方法で注意してください'{foo[bar]}'.format(foo={'bar': 'baz'})
Antoine Pinsard 16

3
これは、アプリケーションがユーザー指定のフォーマット文字列を使用してフォーマットオプションの標準セットを提供する顧客向けアプリケーションに非常に役立ちます。いつも使っています。たとえば、設定ファイルには「messagestring」プロパティがあり、ユーザーはそれを使用して、Your order, number {order[number]} was processed at {now:%Y-%m-%d %H:%M:%S}, will be ready at about {order[eta]:%H:%M:%S}または希望するものを何でも提供できます。これは、古いフォーマッタで同じ機能を提供するよりもはるかにクリーンです。ユーザー提供のフォーマット文字列をさらに強力にします。
タイウィー

35

%format私のテストよりも優れたパフォーマンスを提供します。

テストコード:

Python 2.7.2:

import timeit
print 'format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')")
print '%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')")

結果:

> format: 0.470329046249
> %: 0.357107877731

Python 3.5.2

import timeit
print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')"))
print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')"))

結果

> format: 0.5864730989560485
> %: 0.013593495357781649

見た目はPython2で、違いは小さいのに対し、Python3では%よりもはるかに高速ですformat

サンプルコードを提供してくれた@Chris Cogdonに感謝します。

編集1:

2019年7月にPython 3.7.2で再度テストされました。

結果:

> format: 0.86600608
> %: 0.630180146

大きな違いはありません。Pythonは徐々に改善されていると思います。

編集2:

誰かがコメントでpython 3のf-stringについて言及した後、私はpython 3.7.2で次のコードのテストを行いました。

import timeit
print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')"))
print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')"))
print('f-string:', timeit.timeit("f'{1}{1.23}{\"hello\"}'"))

結果:

format: 0.8331376779999999
%: 0.6314778750000001
f-string: 0.766649943

f-stringはまだより遅いが%、より良いようですformat


42
代わりに、str.formatより多くの機能を提供します(特に、タイプに特化したフォーマットなど'{0:%Y-%m-%d}'.format(datetime.datetime.utcnow()))。パフォーマンスは、すべてのジョブの絶対的な要件ではありません。ジョブに適したツールを使用します。
ミンヒ

36
「時期尚早の最適化がすべての悪の根源」またはドナルドクヌースがかつて言った...
Yatharth Agarwal

22
よく知られているフォーマットスキーム(ほとんどの場合、ニーズに適合している限り)を使用し、2倍の速さは、「時期尚早の最適化」ではなく、単に合理的です。ところで、%オペレーターはprintf知識を再利用することができます。辞書補間は、原理の非常に単純な拡張です。
トビアス2013年

5
私は実際には、ある状況でその逆を経験しました。新しいスタイルのフォーマットはより高速でした。使用したテストコードを提供できますか?
David Sanders

8
例も理由もなく、クレームだけの深刻な無駄な投稿のようです。
kevr 2016年

31

私が今日発見したように、を介し%て文字列をフォーマットする古い方法は、そのままでDecimalは10進固定小数点および浮動小数点演算用のPythonのモジュールをサポートしていません。

例(Python 3.3.5を使用):

#!/usr/bin/env python3

from decimal import *

getcontext().prec = 50
d = Decimal('3.12375239e-24') # no magic number, I rather produced it by banging my head on my keyboard

print('%.50f' % d)
print('{0:.50f}'.format(d))

出力:

0.00000000000000000000000312375239000000009907464850 0.00000000000000000000000312375239000000000000000000

確かに回避策があるかもしれませんが、このformat()方法をすぐに使用することを検討する場合もあります。


1
これはおそらく、新しいスタイルのフォーマットがstr(d)パラメーターを展開する前に呼び出すのに対し、古いスタイルのフォーマットがおそらくfloat(d)最初に呼び出されるためです。
David Sanders

3
あなたはそう思うが、したいstr(d)戻り"3.12375239e-24"、ない"0.00000000000000000000000312375239000000000000000000"
ジャック・

18

Python> = 3.6の場合、F文字列形式のリテラルが新しい友達です。

よりシンプルでクリーンで、パフォーマンスが向上します。

In [1]: params=['Hello', 'adam', 42]

In [2]: %timeit "%s %s, the answer to everything is %d."%(params[0],params[1],params[2])
448 ns ± 1.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [3]: %timeit "{} {}, the answer to everything is {}.".format(*params)
449 ns ± 1.42 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit f"{params[0]} {params[1]}, the answer to everything is {params[2]}."
12.7 ns ± 0.0129 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

15

補足として、ロギングで新しいスタイルのフォーマットを使用するためにパフォーマンスを犠牲にする必要はありません。あなたはに任意のオブジェクトを渡すことができlogging.debuglogging.info実装するなど、__str__魔法の方法を。ロギングモジュールは、メッセージオブジェクト(それが何であれ)を発行する必要があると判断すると、そのstr(message_object)前に呼び出します。だからあなたはこのようなことをすることができます:

import logging


class NewStyleLogMessage(object):
    def __init__(self, message, *args, **kwargs):
        self.message = message
        self.args = args
        self.kwargs = kwargs

    def __str__(self):
        args = (i() if callable(i) else i for i in self.args)
        kwargs = dict((k, v() if callable(v) else v) for k, v in self.kwargs.items())

        return self.message.format(*args, **kwargs)

N = NewStyleLogMessage

# Neither one of these messages are formatted (or calculated) until they're
# needed

# Emits "Lazily formatted log entry: 123 foo" in log
logging.debug(N('Lazily formatted log entry: {0} {keyword}', 123, keyword='foo'))


def expensive_func():
    # Do something that takes a long time...
    return 'foo'

# Emits "Expensive log entry: foo" in log
logging.debug(N('Expensive log entry: {keyword}', keyword=expensive_func))

これはすべてPython 3のドキュメント(https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles)で説明されています。ただし、Python 2.6でも動作します(https://docs.python.org/2.6/library/logging.html#using-arbitrary-objects-as-messages)。

この手法を使用する利点の1つは、書式設定スタイルにとらわれないという事実以外に、たとえばexpensive_func上記の関数のように遅延値を使用できることです。これは、https://docs.python.org/2.6/library/logging.html#optimizationのPythonドキュメントで提供されているアドバイスのよりエレガントな代替手段を提供します


2
これをもっと賛成できればいいのに。これは、とのロギングを可能にするformatパフォーマンスヒットなし-オーバーライドすることでそれをしない__str__正確などloggingのために設計されました-単一の文字(への関数呼び出しを短縮N文字列を定義するための標準的な方法のいくつかに非常に似て感じている) -と遅延することができます関数呼び出し。ありがとうございました!+1
CivFan 2015年

2
これは、logging.Formatter(style='{')パラメータを使用する場合とは結果が異なりますか?
davidA

10

%役立つ1つの状況は、正規表現をフォーマットする場合です。例えば、

'{type_names} [a-z]{2}'.format(type_names='triangle|square')

引き上げるIndexError。この状況では、以下を使用できます。

'%(type_names)s [a-z]{2}' % {'type_names': 'triangle|square'}

これは、正規表現をと書くことを避け'{type_names} [a-z]{{2}}'ます。これは、2つの正規表現があり、1つはフォーマットなしで単独で使用され、両方の連結がフォーマットされている場合に役立ちます。


3
または単に使用します'{type_names} [a-z]{{2}}'.format(type_names='triangle|square')。これ.format()は、すでにパーセント文字が含まれている文字列を使用するときに役立つと言っているようなものです。承知しました。あなたはそれらから逃げなければなりません。
Alfe

1
@Alfeあなたは正しい、そしてそれが答えが"One situation where % may help is when you are formatting regex expressions."具体的に始まる理由です。具体的にa=r"[a-z]{2}"は、2つの異なる最終式(たとえばc1 = b + ac2 = a)で使用される正規表現のチャンクであると仮定します。ed c1する必要があるformat(たとえばb、ランタイムをフォーマットする必要がある)と仮定しますが、そうする必要c2はありません。そして、あなたは必要a=r"[a-z]{2}"のためにc2a=r"[a-z]{{2}}"のためにc1.format(...)
ホルヘレイタオ2017年

7

バージョン3.6以降、次のようなfstringを使用できることを追加します

foo = "john"
bar = "smith"
print(f"My name is {foo} {bar}")

与える

私の名前はジョン・スミスです

すべてが文字列に変換されます

mylist = ["foo", "bar"]
print(f"mylist = {mylist}")

結果:

mylist = ['foo'、 'bar']

他のフォーマットメソッドのように、関数を渡すことができます

print(f'Hello, here is the date : {time.strftime("%d/%m/%Y")}')

例えば与える

こんにちは、ここに日付があります:16/04/2018



2

Python 3.6.7の比較:

#!/usr/bin/env python
import timeit

def time_it(fn):
    """
    Measure time of execution of a function
    """
    def wrapper(*args, **kwargs):
        t0 = timeit.default_timer()
        fn(*args, **kwargs)
        t1 = timeit.default_timer()
        print("{0:.10f} seconds".format(t1 - t0))
    return wrapper


@time_it
def new_new_format(s):
    print("new_new_format:", f"{s[0]} {s[1]} {s[2]} {s[3]} {s[4]}")


@time_it
def new_format(s):
    print("new_format:", "{0} {1} {2} {3} {4}".format(*s))


@time_it
def old_format(s):
    print("old_format:", "%s %s %s %s %s" % s)


def main():
    samples = (("uno", "dos", "tres", "cuatro", "cinco"), (1,2,3,4,5), (1.1, 2.1, 3.1, 4.1, 5.1), ("uno", 2, 3.14, "cuatro", 5.5),) 
    for s in samples:
        new_new_format(s)
        new_format(s)
        old_format(s)
        print("-----")


if __name__ == '__main__':
    main()

出力:

new_new_format: uno dos tres cuatro cinco
0.0000170280 seconds
new_format: uno dos tres cuatro cinco
0.0000046750 seconds
old_format: uno dos tres cuatro cinco
0.0000034820 seconds
-----
new_new_format: 1 2 3 4 5
0.0000043980 seconds
new_format: 1 2 3 4 5
0.0000062590 seconds
old_format: 1 2 3 4 5
0.0000041730 seconds
-----
new_new_format: 1.1 2.1 3.1 4.1 5.1
0.0000092650 seconds
new_format: 1.1 2.1 3.1 4.1 5.1
0.0000055340 seconds
old_format: 1.1 2.1 3.1 4.1 5.1
0.0000052130 seconds
-----
new_new_format: uno 2 3.14 cuatro 5.5
0.0000053380 seconds
new_format: uno 2 3.14 cuatro 5.5
0.0000047570 seconds
old_format: uno 2 3.14 cuatro 5.5
0.0000045320 seconds
-----

3
各例を数回実行する必要があります。1回の実行では誤解を招く可能性があります。たとえば、オペレーティングシステムが一般的にビジーなため、コードの実行が遅れる可能性があります。docs:docs.python.org/3/library/timeit.htmlを参照してください。(素敵なアバター、ガイブラシ!)
jake77

1

ただし、1つのことは、中括弧をネストしている場合でも、フォーマットでは機能せず、機能することです%

例:

>>> '{{0}, {1}}'.format(1,2)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    '{{0}, {1}}'.format(1,2)
ValueError: Single '}' encountered in format string
>>> '{%s, %s}'%(1,2)
'{1, 2}'
>>> 

2
あなたはこれを行うことができますが、私はそれが素晴らしい '{{{0}、{1}}}'であることに同意します。format(1、2)
Sylvan LE DEUNFF '15

ネストされたキーワードの中括弧が機能し、きれいです。
CivFan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.