16

次のような変数名のリストがあります。

['foo', 'bar', 'baz']

(最初に、変数のリストを変換する方法を尋ねました。以下の Greg Hewgill の回答を参照してください。)

これを、キーが変数名 (文字列として) で、値が変数の値である辞書に変換するにはどうすればよいですか?

{'foo': foo, 'bar': bar, 'baz': baz}

改めて質問させていただきましたが、以下のようになりました。

d = {}
for name in list_of_variable_names:
    d[name] = eval(name)

それは改善できますか?

Update、なぜ私がこれをやりたいのかという質問(コメントで)に答えます:

補間する名前と値の辞書を含む文字列に % 演算子を使用することがよくあります。多くの場合、文字列内の名前は単なるローカル変数の名前です。だから(以下の答えで)私はこのようなことができます:

message = '''Name: %(name)s
ZIP: %(zip)s

Dear %(name)s,
...''' % dict((x, locals()[x]) for x in ['name', 'zip'])
4

4 に答える 4

16

フィルタリングを忘れてくださいlocals()!フォーマット文字列に指定する辞書には、未使用のキーを含めることができます。

>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> locals()
{'name': 'foo', 'zip': 123, ... 'unused': 'whoops!', ...}
>>> '%(name)s %(zip)i' % locals()
'foo 123'

Python 3.6の新しいf-string 機能locals()により、使用は不要になりました。

>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> f'{zip: >5} {name.upper()}'
'  123 FOO'
于 2008-10-23T20:29:33.377 に答える
5

リストまたはジェネレータ内包表記を使用して、辞書を直接インスタンス化するために使用されるキー、値のタプルのリストを作成できます。最良の方法は次のとおりです。

dict((name, eval(name)) for name in list_of_variable_names)

さらに、たとえば、変数がローカル シンボル テーブルに存在することがわかっている場合は、変数をローカルから直接参照することで、危険な eval から身を守ることができます。

dict((name, locals()[name]) for name in list_of_variable_names)

最終更新の後、以下の答えが本当にあなたが望んでいるものだと思います。制御する文字列を使用した文字列展開にこれを使用している場合は、 locals() を文字列展開に直接渡すだけで、目的の値が選択されます

ただし、これらの文字列が外部ソース (翻訳ファイルなど) から取得される可能性がある場合は、locals() をフィルタリングすることをお勧めします。

于 2008-10-23T18:49:48.057 に答える
4

元のリストには変数[foo, bar, baz]が含まれていません。リストした変数と同じを参照する要素が含まれているだけです。これは、同じ値を参照する 2 つの異なる変数名を使用できるためです。

したがって、リスト自体には、オブジェクトを参照する他の名前に関する情報は含まれていません。配列の最初の要素には名前fooがありますが、名前もありa[0]ます(配列が と呼ばれると仮定しますa)。次のコードを実行するquuxと、同じオブジェクトも参照されます。

quux = a[0]

更新:そのために使用できるのは正しいですeval()が、その使用は一般的に推奨されていません。Python は__dict__、現在のモジュールのシンボル テーブルを含む名前付きの特別なメンバーを提供します。だからあなたはできる:

import __main__
d = dict((x, __main__.__dict__[x]) for x in list_of_variable_names)

コードimport __main__が名前のないメイン モジュールにある場合は、Python の癖です。

于 2008-10-23T18:35:35.370 に答える
1

効率的ではありませんが、呼び出しなしeval:

dict((k,v) for (k,v) in globals().iteritems() if k in list_of_variable_names)

また

dict((k,v) for (k,v) in vars().iteritems() if k in list_of_variable_names)

あなたが望むものに応じて。

于 2008-10-23T18:54:33.553 に答える