2009-10-25 9 views
9

では動作しませんが、それは次のようにTypeError.Theコードがあり提起:str.format(リスト)私は出力フォーマットされたリストに交換用のフィールドに負のインデックスを使用してPythonの

 
>>> a=[1,2,3] 
>>> a[2] 
3 
>>> a[-1] 
3 
>>> 'The last:{0[2]}'.format(a) 
'The last:3' 
>>> 'The last:{0[-1]}'.format(a) 
Traceback (most recent call last): 
    File "", line 1, in 
TypeError: list indices must be integers, not str 
+0

は、フォーマット関数定義の監視のように聞こえます – barkmadley

+2

Pythonのバグベースに関連するバグ - http://bugs.python.org/issue7951。要するに、この問題は、これを実装することの副作用と、それが悪いコードにつながる可能性があるという事実のために、ドキュメントのバグとして扱われています。 – Sam

答えて

12

それは私がフォーマットの文字列仕様でデザイン・グリッチと呼ぶものです。パーthe docs

element_index  ::= integer | index_string 

しかし、残念ながら、-1は "整数" ではありません - それは表現です。単項マイナス演算子は特に優先順位が高くないので、例えばprint(-2**2)-4を発行します - 別の共通の問題であり、おそらく設計上の不具合(**演算子が優先順位が高いため、より低い優先度の単項で要求された変更記号-)。

$ python3 -c "print('The last:{0[2+2]}'.format({'2+2': 23}))" 
The last:23 

わからない:例えば -

整数(ただし、例えば、式)ではありませんフォーマット文字列のその位置にあるものはすべてdictの引数インデックスに、文字列として扱われますこれは、Pythonのtracに問題を提起する価値があるが、それは:-(確かにやや意外な行動だ

+0

面白い! -2 ** 2は-4に等しいので、これは数学で使われる規約であるので、これはとても良いことだと思います。 element_index :: = "signed_integer"のようなものが意味をなさないでしょうか? – EOL

1

あなたが掘削を開始するといくつかの問題は、ここにあるかどうか:。

項目が問題の "と呼ばれていますelement_index "は整数であると定義される。問題1:ユーザーが「整数」から言語リファレンスマニュアルへのリンクをたどらない限り、-1は整数ではなく式であると認識されます。ところで、「文書化されているように働く」と言いたくなる人は、最初に賛否両論7を見るべきです:-)

好ましい解決法: "element_index"が整数の前にオプションの ' - 'を持つことができるように定義を変更します。

これは整数です。それほど高速ではありません...後で、「 '[index]'式の式は__getitem__()を使ってインデックスルックアップを実行します」というメッセージが表示される問題3: '[element_index]'(インデックスが定義されていません)としてください。

問題4:誰もが頭の上を知っているわけではありません。__getitem__()より明確なドキュメントが必要です。

ここでは整数と同様にdictを使用できますか?はい、問題が2つあります。

element_indexは整数ですか?はい、それは辞書で動作します。我々はまた、非整数​​の文字列を使用することができるようです

>>> "{0[2]}".format({2: 'int2'}) 
'int2' 

が、これは、より明示的なドキュメントを必要とする(問題5):

>>> "{0[foo]}".format({'foo': 'bar'}) 
'bar' 

しかし、我々はできません

>>> "{0[2]}".format({'2': 'str2'}) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 2 
>>> "{0['2']}".format({'2': 'str2'}) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: "'2'" 

問題7::「2」(問題点6)のようなキーで辞書を使用する「整数」は本当に「decimalinteger」であることを文書化する必要があることを...ただし0x22と0b11にはSTRとして扱われ、及び010( "octalinteger")が10ではなく8として扱われる:

>>> "{0[010]}".format('abcdef') 
'a' 

更新: ""」
ルール
PEP 3101本当の物語アイテムキーの解析は非常に簡単です。数字で始まる場合は数字として扱い、それ以外の場合は文字列として扱います。

キーは引用符で区切られていないため、指定できません書式文字列内の任意の辞書キー(例えば、文字列「10」または「: - 」)。
""

1

正解、正しく動作しません。解決策:私は、多くの場合、設定オプションとしてPythonのフォーマット文字列を取る

>>> 'The last:{0}'.format(a[-1]) 
'The last:3' 
+1

これは疑問をひきつけます:なぜ、制限されたシーケンスの索引付け、制限付きの辞書の検索、属性の検索機能を書式文字列で設計するのが難しいのですか? –

+0

うん、私を打つ。 –

0

- キーワード引数の特定の、知られているリストを提供するフォーマット文字列を持ちます。したがって、書式文字列内で可変長リストのインデックスを前方または後方に指定するのは、まさに私が必要とするものです。

私は負のインデックスを機能させるために、このハックを書いた

string_to_tokenise = "Hello_world" 
tokens = re.split(r"[^A-Z\d]+", string_to_tokenise, flags=re.I) 
token_dict = {str(i) if i < 0 else i: tokens[i] for i in range(-len(tokens) + 1, len(tokens))} 
print "{thing[0]} {thing[-1]}".format(thing=token_dict) 

結果:

Hello world 

をだからではなく、トークンのリストに渡すので、私はAを作成し、説明するために、 0からlen(..) - 1までのリストを索引付けするために必要なすべての整数キーを含む辞書、および-1から - (len(..) - 1)の最後までの索引付けのための負の整数キーを追加するしかし、これらのキーは整数から文字列に変換されます。形式がそれらを解釈する方法です。

関連する問題