48

私は最近(ついに?)使い始めました.format()が、おそらく少しあいまいな質問があります。

与えられた

res = ['Irene Adler', 35,  24.798]

(1) print('{0[0]:10s} {0[1]:5d} {0[2]:.2f}'.format(res))
(2) print('{:{}s} {:{}d} {:{}f}'.format(res[0], 10, res[1], 5, res[2], .2))

うまく機能し、両方が印刷されます:

Irene Adler    35 24.80
Irene Adler    35 24.80

(1)のようにきちんとしたリストを扱えるとは知りませんでした。%以前、古いフォーマットのフィールド幅引数(2)について見てきました。

私の質問は、(1)と(2)を組み合わせたこのようなことをしたいということです:

(3) print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, 10, 5, .2))

しかし、私はこれを行うことができず、これが可能であるかどうかをドキュメントから理解することはできませんでした。印刷するリストと幅の引数を指定するだけでよいでしょう。

ちなみに、私もこれを試しました(運がない):

args = (10, 5, .2)
(4) print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, args))

どちらの場合も、次のようになりました。

D:\Users\blabla\Desktop>python tmp.py
Traceback (most recent call last):
  File "tmp.py", line 27, in <module>
    print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, 10, 5, .2))
ValueError: cannot switch from manual field specification to automatic field numbering

D:\Users\blabla\Desktop>python tmp.py
Traceback (most recent call last):
  File "tmp.py", line 35, in <module>
    print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, args))
ValueError: cannot switch from manual field specification to automatic field numbering

またzip()、運が悪かったので、2つのシーケンスを組み合わせてみました。

私の質問は:

(3)と(4)で失敗したことを効果的に実行するためにリストを指定できますか(これが可能であれば、正しい構文を使用していません)、その場合はどうすればよいですか?

4

2 に答える 2

67

エラーメッセージ

ValueError: cannot switch from manual field specification to automatic field numbering

ほとんどすべてを言います:あなたはどこにでも明示的なフィールドインデックスを与える必要があります、そして

print('{0[0]:{1}s} {0[1]:{2}d} {0[2]:{3}f}'.format(res, 10, 5, .2))

正常に動作します。

于 2012-06-04T00:36:35.757 に答える
2

を使用する場合は.format(res, args)、次のようなフォーマット文字列ですべてのインデックスを指定できます。

>>> print('{0[0]:{1[0]}s} {0[1]:{1[1]}d} {0[2]:{1[2]}f}'.format(res, args))
Irene Adler    35 24.80

ただし、インデックスなしのフォーマット文字列を作成する場合は、連続するペアのタプルを作成できます(res[0], args[0], ... , res[-1], args[-1])

これは、このイディオムによって行われます。

>>> sum(zip(res, args), ())
('Irene Adler', 10, 35, 5, 24.798, 0.2)

*これを( -argumentを介して)簡略化されたフォーマット文字列に渡すことができます。

>>> fmt = sum(zip(res, args), ())
>>> print('{:{}s} {:{}d} {:{}f}'.format(*fmt))
('Irene Adler', 10, 35, 5, 24.798, 0.2)

もちろん、これは1行で実行できます。

>>> print('{:{}s} {:{}d} {:{}f}'.format(*sum(zip(res, args), ())))
Irene Adler    35 24.80

読みやすくするために、変換に次の名前を付けます。

def flat_pairs(iterable1, iterable2):
    return sum(zip(iterable1, iterable2), ())

# (...)

>>> print('{:{}s} {:{}d} {:{}f}'.format(*flat_pairs(res, args)))
Irene Adler    35 24.80

最後の1つは、読みやすさ、利便性、そしてもちろん、Pythonの考え方を示すことの間の合理的なトレードオフだと思います。これは、そのようなもので遊ぶ主な動機です。

于 2016-11-03T08:47:17.147 に答える