名前付きタプルを辞書に変換する


148

私はPythonで名前付きタプルクラスを持っています

class Town(collections.namedtuple('Town', [
    'name', 
    'population',
    'coordinates',
    'population', 
    'capital', 
    'state_bird'])):
    # ...

Townのインスタンスを辞書に変換したいのですが。タウンのフィールドの名前や数に厳密に結び付けられたくありません。

フィールドを追加したり、まったく異なる名前のタプルを渡して辞書を取得したりする方法はありますか?

他の誰かのコードのように元のクラス定義を変更することはできません。だから私は町のインスタンスを取り、それを辞書に変換する必要があります。


2
ところで...タブ補完またはdirコマンドを見てください。これは、オブジェクトのフィールドを表示します... _asdict関数を直接表示します。
Corley Brigman、2014年

あなたが本当にやりたいことはdict'namedtuple'の代わりにからサブクラスを作成し、namedtupleを初期化子に渡すようです。Cxxに慣れている場合class Town(x)は、コンストラクターではないことを覚えておいてくださいdef __init__(self, *args, **kwargs)
Corley Brigman、2014年

他の人のコードのように元のクラスを変更することはできません。だから私はnamedtoubleからサブクラス化し
なければなり

@CorleyBrigmanこれについてもっと説明してもらえますか?私は名前のついたおもちゃのドキュメントを見つけようとしたり、それを呼び出すことができるものを見つけたりして、その方法を理解できませんでした。(ここでもpythonは私の最強の言語ではありません)
私なしではそれはちょうどAweso

2
どの部分?dirは単なるpythonの組み込みです... コンソールまたはスクリプトで任意の pythonオブジェクト上で実行できます(印刷したり、何でもできるリストを返します)、そして(ほぼ)オブジェクトのすべての属性。未知のオブジェクトがどのように機能するかを理解しようとしている場合に役立ちます。
Corley Brigman、2014年

回答:


268

TL; DR:これのために_asdict提供されたメソッドがあります。

これは使用法のデモです:

>>> fields = ['name', 'population', 'coordinates', 'capital', 'state_bird']
>>> Town = collections.namedtuple('Town', fields)
>>> funkytown = Town('funky', 300, 'somewhere', 'lipps', 'chicken')
>>> funkytown._asdict()
OrderedDict([('name', 'funky'),
             ('population', 300),
             ('coordinates', 'somewhere'),
             ('capital', 'lipps'),
             ('state_bird', 'chicken')])

これは、namedtuplesのドキュメント化されたメソッドです。つまり、Python 通常の規則とは異なり、メソッド名の先頭のアンダースコアは使用をやめさせるためのものではありません。namedtuplesに追加され、他の方法に加えて、_make_replace_source_fields、それだけで試してみて、可能なフィールド名との競合を防ぐために、アンダースコアを持っています。


注: 2.7.5 <pythonバージョン<3.5.0コードが実際に出回っている場合、このバージョンが表示されることがあります。

>>> vars(funkytown)
OrderedDict([('name', 'funky'),
             ('population', 300),
             ('coordinates', 'somewhere'),
             ('capital', 'lipps'),
             ('state_bird', 'chicken')])

しばらくの間、ドキュメンテーションはそれ_asdictが時代遅れであると述べていて(ここを参照)、組み込みメソッドvarsを使用することを提案しました。そのアドバイスは今では時代遅れです。サブクラス化に関連するバグを修正するために__dict__、namedtuplesに存在していたプロパティがこのコミットによって再び削除されました


1
_asdict標準ライブラリでエイリアスされるべきでないことを示唆する確立された前例があるかどうか誰かが知っていasdictますか?
神戸ジョン2016年

1
@KobeJohnでは"asdict"、タプル名の1つになることはできません。
シャドウトーカー2016年

28

namedtupleこのためのインスタンスに組み込みのメソッドがあります_asdict

コメントで説明されているように、一部のバージョンでvars()はそれも可能ですが、_asdict信頼できるはずですが、ビルドの詳細に大きく依存しています。一部のバージョンで_asdictは非推奨としてマークされていましたが、コメントでは、3.4の時点ではこれが当てはまらないことが示されています。


1
私はdownvoterありませんでしたが、ので、それは可能性が_asdict方法がされています(VARSの賛成で)のpython3で廃止
WIM

逆に、vars一部の古いバージョンでは動作しないようです。2.7 TypeErrorでは、そのバージョンのnamedtupleクラスに__dict__属性がないため、が発生します。
Peter DeGlopper 2014年

はい、マルティンと私はそれをここで議論しました。それは2.7 btwの新しいバージョンで動作します(私は2.7.6で動作します)
wim

上記のコメントの編集ウィンドウを過ぎた-2.7.5で失敗するため、2.7.6以降で新しい必要があります。私の2.7.5ビルドがオフでない限り、Martijnはリンクされた答えにあったので?とにかく、それが2.7.5で動作するかどうかは、ビルドの詳細に依存するようです。
Peter DeGlopper 2014年

8
ヘッドアップ:_asdictは廃止されず(そしてOrderedDictを返す)、varsはPython 3.4でエラーを生成します(namedtuplesのdict属性の削除により)。
Alexander Huszagh、2015年

2

Ubuntu 14.04 LTSバージョンのpython2.7およびpython3.4では、この__dict__プロパティは期待どおりに機能しました。_asdict この方法はまた働いたが、私の代わりにローカライズされた不均一なAPIを標準に定義され、均一な、プロパティのAPIを使用することを傾けています。

$ python2.7

# Works on:
# Python 2.7.6 (default, Jun 22 2015, 17:58:13)  [GCC 4.8.2] on linux2
# Python 3.4.3 (default, Oct 14 2015, 20:28:29)  [GCC 4.8.4] on linux

import collections

Color = collections.namedtuple('Color', ['r', 'g', 'b'])
red = Color(r=256, g=0, b=0)

# Access the namedtuple as a dict
print(red.__dict__['r'])  # 256

# Drop the namedtuple only keeping the dict
red = red.__dict__
print(red['r'])  #256

見て辞書を辞書表すsoemthingを取得するためのセマンティックな方法である(少なくとも私の知る限り)、。


主要なpythonバージョンとプラットフォーム、およびそれらに対するのサポートの表を蓄積するとよいでしょう__dict__。現在、上記のように1つのプラットフォームバージョンと2つのpythonバージョンしかありません。

| Platform                      | PyVer     | __dict__ | _asdict |
| --------------------------    | --------- | -------- | ------- |
| Ubuntu 14.04 LTS              | Python2.7 | yes      | yes     |
| Ubuntu 14.04 LTS              | Python3.4 | yes      | yes     |
| CentOS Linux release 7.4.1708 | Python2.7 | no       | yes     |
| CentOS Linux release 7.4.1708 | Python3.4 | no       | yes     |
| CentOS Linux release 7.4.1708 | Python3.6 | no       | yes     |

1
Linux-3.10.0-693.el7.x86_64-x86_64-with-centos-7.4.1708-Core、Python 2.7-機能__dict__しません。
gbtimmon 2018

-1

ケース1:1次元のタプル

TUPLE_ROLES = (
    (912,"Role 21"),
    (913,"Role 22"),
    (925,"Role 23"),
    (918,"Role 24"),
)


TUPLE_ROLES[912]  #==> Error because it is out of bounce. 
TUPLE_ROLES[  2]  #==> will show Role 23.
DICT1_ROLE = {k:v for k, v in TUPLE_ROLES }
DICT1_ROLE[925] # will display "Role 23" 

ケース#2:2次元のタプル
例:DICT_ROLES [961]#は 'Back-End Programmer'を表示します

NAMEDTUPLE_ROLES = (
    ('Company', ( 
            ( 111, 'Owner/CEO/President'), 
            ( 113, 'Manager'),
            ( 115, 'Receptionist'),
            ( 117, 'Marketer'),
            ( 119, 'Sales Person'),
            ( 121, 'Accountant'),
            ( 123, 'Director'),
            ( 125, 'Vice President'),
            ( 127, 'HR Specialist'),
            ( 141, 'System Operator'),
    )),
    ('Restaurant', ( 
            ( 211, 'Chef'), 
            ( 212, 'Waiter/Waitress'), 
    )),
    ('Oil Collector', ( 
            ( 211, 'Truck Driver'), 
            ( 213, 'Tank Installer'), 
            ( 217, 'Welder'),
            ( 218, 'In-house Handler'),
            ( 219, 'Dispatcher'),
    )),
    ('Information Technology', ( 
            ( 912, 'Server Administrator'),
            ( 914, 'Graphic Designer'),
            ( 916, 'Project Manager'),
            ( 918, 'Consultant'),
            ( 921, 'Business Logic Analyzer'),
            ( 923, 'Data Model Designer'),
            ( 951, 'Programmer'),
            ( 953, 'WEB Front-End Programmer'),
            ( 955, 'Android Programmer'),
            ( 957, 'iOS Programmer'),
            ( 961, 'Back-End Programmer'),
            ( 962, 'Fullstack Programmer'),
            ( 971, 'System Architect'),
    )),
)

#Thus, we need dictionary/set

T4 = {}
def main():
    for k, v in NAMEDTUPLE_ROLES:
        for k1, v1 in v:
            T4.update ( {k1:v1}  )
    print (T4[961]) # will display 'Back-End Programmer'
    # print (T4) # will display all list of dictionary

main()

-1

_asdict()がない場合は、次のように使用できます。

def to_dict(model):
    new_dict = {}
    keys = model._fields
    index = 0
    for key in keys:
        new_dict[key] = model[index]
        index += 1

    return new_dict

-5

Python 3.辞書に必要なインデックスとして任意のフィールドを辞書に割り当てます。「名前」を使用しました。

import collections

Town = collections.namedtuple("Town", "name population coordinates capital state_bird")

town_list = []

town_list.append(Town('Town 1', '10', '10.10', 'Capital 1', 'Turkey'))
town_list.append(Town('Town 2', '11', '11.11', 'Capital 2', 'Duck'))

town_dictionary = {t.name: t for t in town_list}

名前がわかるので役に立ちません。それはブラインドメソッドでなければなりません
ミッチェルカリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.