Python - 文字列を出力するときにプレースホルダーとして数値辞書キーを使用しますか?

okwaves2024-01-25  7

次のコードがあります:

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))

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。