次のコードがあります:
board_dic = {
0: '_',
1: '_',
2: '_',
3: '_',
4: '_',
5: '_',
6: '_',
7: '_',
8: '_',
}
print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(**board_dic)
実行時の出力は次のとおりです。
line 28, in <module>
print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(**board_dic))
IndexError: Replacement index 0 out of range for positional args tuple
これに対する解決策はどこにも見つかりません。 board_dic のキーを「a」、「b」、「c」などの文字列に置き換え、print ステートメントのプレースホルダーを「a」、「b」、「c」などに置き換えるとします。そうすれば、print ステートメントは問題なく実行されます。ただし、問題は特に数値キー辞書の値にあるようです。
これはなぜですか? どうすれば修正できますか?
この結果は必要ですか? |_|_|_| |_|_|_| |_|_|_|
– アーメド・マムドゥ
2020 年 9 月 3 日 16:04
------------------------
何を探すべきかがわかっている場合は、ここで説明します。
field_name 自体は、数値またはキーワードのいずれかの arg_name で始まります。数値の場合は位置引数を参照し、キーワードの場合は名前付きキーワード引数を参照します。書式文字列内の数値 arg_name が 0、1、2、… の順序で並んでいる場合、(一部だけではなく) すべて省略でき、数値 0、1、2、… がその順序で自動的に挿入されます。 arg_name は引用符で区切られていないため、フォーマット文字列内で任意の辞書キー (文字列「10」や「:-]」など) を指定することはできません。
簡単に言うと、「{0} {1}」.format(...) は、「{0} を format(...) の最初の位置引数に置き換え、{1} を 2 番目の位置引数に置き換える」ことを意味します。 .
位置引数は、関数呼び出しでパラメータ名を指定せずに渡される引数です。たとえば、format(1, 2, c=3) では、1 と 2 は位置引数で、c=3 はキーワード引数です。
ただし、**board_dic 構文ではキーワード引数を指定します。 format(**board_dic) は format(0='_', 1='_', 2='_', ...)1 と同等であり、位置引数はありません。したがって、{0}、{1}、{2} などを使用して 1 番目、2 番目、3 番目などの位置引数を取得することは失敗します。
辞書を渡すには整数キーをフォーマットするには、これを使用できます:
print("|{d[0]}|{d[1]}|{d[2]}|\n|...".format(d=board_dic))
1数字をキーワードとして使用できないことは別の問題です。
------------------------
キーを使用して dict 値を str.format メソッドの位置引数に変換するには、dict の長さの範囲を dict の get メソッドにマップし、出力シーケンスを引数として解凍します。
print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(*map(board_dic.get, range(len(board_dic)))))
------------------------
使用時g フォーマット文字列、{1} のようなプレースホルダーは、「format()」の n 番目の引数を表します。これは、名前付きキーワード引数とは異なります。 **board_dic を使用すると、これらがキーワード引数に分解されます。これが期待どおりに動作しない理由です。
代わりに、単一の * を使用した位置引数を使用する必要があります。しかし、その後、別の問題に直面することになります。私が覚えている限り、辞書の順序付けは Python 3.7 の言語仕様の一部にしか組み込まれていません。以前のバージョンではすでに安定していましたが、それは実装の詳細であり、他のバージョン (pypy、jython など) では保証されていませんでした。
したがって、これが機能することを 100% 確実にするには、並べ替える必要があります。
キーは数値であるため、board_dic.items() で単純に並べ替えることができます。これにより、安定した代替が得られます。
私たちは有効な値を抽出する必要があります。これは、単純なリスト内包表記で行うことができます。
その変更後は、辞書に欠落している数字が含まれていない限り、出力は 100% 正確であると確信できます。
単一の「位置引数展開」を使用して、結果のリストを .format() で使用できます。
board_dic = {
0: '_',
1: '_',
2: '_',
3: '_',
4: '_',
5: '_',
6: '_',
7: '_',
8: '_',
}
values = [value for _, value in sorted(board_dic.items())]
print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(*values))