第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

實(shí)現(xiàn)嵌套字典的最佳方法是什么?

實(shí)現(xiàn)嵌套字典的最佳方法是什么?

實(shí)現(xiàn)嵌套字典的最佳方法是什么?我有一個(gè)數(shù)據(jù)結(jié)構(gòu),實(shí)質(zhì)上相當(dāng)于一個(gè)嵌套字典。假設(shè)它看起來是這樣的:{'new jersey': {'mercer county': {'plumbers': 3,                                   'programmers': 81},                 'middlesex county': {'programmers': 81,                                      'salesmen': 62}},  'new york': {'queens county': {'plumbers': 9,                                 'salesmen': 36}}}現(xiàn)在,維護(hù)和創(chuàng)建它是非常痛苦的;每次我有一個(gè)新的州/縣/專業(yè)時(shí),我都必須通過討厭的嘗試/捕捉塊創(chuàng)建底層字典。此外,如果我想遍歷所有的值,我必須創(chuàng)建惱人的嵌套迭代器。我還可以使用元組作為鍵,如下所示:{('new jersey', 'mercer county', 'plumbers'): 3,  ('new jersey', 'mercer county', 'programmers'): 81,  ('new jersey', 'middlesex county', 'programmers'): 81,  ('new jersey', 'middlesex county', 'salesmen'): 62,  ('new york', 'queens county', 'plumbers'): 9,  ('new york', 'queens county', 'salesmen'): 36}這使得迭代這些值變得非常簡(jiǎn)單和自然,但是進(jìn)行聚合和查看字典的子集(例如,如果我只想逐州進(jìn)行)在語法上是比較痛苦的?;旧?,有時(shí)我想把嵌套字典看作是一個(gè)平面字典,有時(shí)我想把它看作一個(gè)復(fù)雜的層次結(jié)構(gòu)。我可以在一個(gè)類中完成這一切,但似乎已經(jīng)有人這樣做了?;蛘?,似乎有一些非常優(yōu)雅的句法結(jié)構(gòu)來做到這一點(diǎn)。我怎么能做得更好?增編:我知道setdefault()但它并沒有提供清晰的語法。另外,您創(chuàng)建的每個(gè)子字典都需要有setdefault()手動(dòng)設(shè)置。
查看完整描述

3 回答

?
撒科打諢

TA貢獻(xiàn)1934條經(jīng)驗(yàn) 獲得超2個(gè)贊

在Python中實(shí)現(xiàn)嵌套字典的最佳方法是什么?

實(shí)施__missing__在.上dict類來設(shè)置和返回一個(gè)新實(shí)例。

這種方法是可用的。(并記錄在案)自從Python2.5之后,和(對(duì)我來說特別有價(jià)值)很漂亮的指紋就像個(gè)普通的白癡,而不是丑陋的打印一個(gè)自動(dòng)形象的默認(rèn):

class Vividict(dict):
    def __missing__(self, key):
        value = self[key] = type(self)() # retain local pointer to value
        return value                     # faster to return than dict lookup

(注self[key]是在任務(wù)的左邊,所以這里沒有遞歸。)

說你有一些數(shù)據(jù):

data = {('new jersey', 'mercer county', 'plumbers'): 3,
        ('new jersey', 'mercer county', 'programmers'): 81,
        ('new jersey', 'middlesex county', 'programmers'): 81,
        ('new jersey', 'middlesex county', 'salesmen'): 62,
        ('new york', 'queens county', 'plumbers'): 9,
        ('new york', 'queens county', 'salesmen'): 36}

以下是我們的使用代碼:

vividict = Vividict()for (state, county, occupation), number in data.items():
    vividict[state][county][occupation] = number

現(xiàn)在:

>>> import pprint>>> pprint.pprint(vividict, width=40){'new jersey': {'mercer county': {'plumbers': 3,
                                  'programmers': 81},
                'middlesex county': {'programmers': 81,
                                     'salesmen': 62}},
 'new york': {'queens county': {'plumbers': 9,
                                'salesmen': 36}}}

批評(píng)

對(duì)這類容器的批評(píng)是,如果用戶拼錯(cuò)了密鑰,我們的代碼可能會(huì)悄然失?。?/trans>

>>> vividict['new york']['queens counyt']{}

此外,我們的數(shù)據(jù)中還有一個(gè)拼寫錯(cuò)誤的縣:

>>> pprint.pprint(vividict, width=40){'new jersey': {'mercer county': {'plumbers': 3,
                                  'programmers': 81},
                'middlesex county': {'programmers': 81,
                                     'salesmen': 62}},
 'new york': {'queens county': {'plumbers': 9,
                                'salesmen': 36},
              'queens counyt': {}}}

說明:

我們只是提供我們類的另一個(gè)嵌套實(shí)例Vividict無論何時(shí)訪問密鑰,但缺少密鑰。(返回值賦值很有用,因?yàn)樗苊饬宋覀冊(cè)贒ECT上額外調(diào)用getter,而且不幸的是,我們不能在設(shè)置它時(shí)返回它。)

注意,這些是與最不正確的答案相同的語義,但在代碼-nosklo實(shí)現(xiàn)的一半行中:

class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

示范使用

下面只是一個(gè)示例,說明如何輕松地使用這個(gè)dict創(chuàng)建嵌套的dict結(jié)構(gòu)。這可以快速地創(chuàng)建一個(gè)層次化的樹結(jié)構(gòu),就像您想要的那樣。

import pprintclass Vividict(dict):
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value

d = Vividict()d['foo']['bar']d['foo']['baz']d['fizz']['buzz']d['primary']['secondary']['tertiary']['quaternary']pprint.pprint(d)

產(chǎn)出:

{'fizz': {'buzz': {}},
 'foo': {'bar': {}, 'baz': {}},
 'primary': {'secondary': {'tertiary': {'quaternary': {}}}}}

正如最后一行所示,它打印得很漂亮,便于手工檢查。但是如果您想要直觀地檢查您的數(shù)據(jù),請(qǐng)執(zhí)行__missing__要將其類的新實(shí)例設(shè)置為鍵并返回,這是一個(gè)更好的解決方案。

與之相反的其他備選辦法:

dict.setdefault

雖然提問者認(rèn)為這是不干凈的,但我發(fā)現(xiàn)這比Vividict我自己。

d = {} # or dict()for (state, county, occupation), number in data.items():
    d.setdefault(state, {}).setdefault(county, {})[occupation] = number

現(xiàn)在:

>>> pprint.pprint(d, width=40){'new jersey': {'mercer county': {'plumbers': 3,
                                  'programmers': 81},
                'middlesex county': {'programmers': 81,
                                     'salesmen': 62}},
 'new york': {'queens county': {'plumbers': 9,
                                'salesmen': 36}}}

拼寫錯(cuò)誤會(huì)引起噪音,而且不會(huì)使我們的數(shù)據(jù)充斥著糟糕的信息:

>>> d['new york']['queens counyt']Traceback (most recent call last):
  File "<stdin>", line 1, in <module>KeyError: 'queens counyt'

此外,我認(rèn)為setDefault在循環(huán)中使用時(shí)效果很好,而且您也不知道要為鍵獲取什么,但是重復(fù)使用會(huì)帶來很大的負(fù)擔(dān),而且我認(rèn)為沒有人會(huì)想要保持以下內(nèi)容:

d = dict()d.setdefault('foo', {}).setdefault('bar', {})d.setdefault('foo', {}).setdefault('baz', {})d.setdefault('fizz', {}).setdefault
('buzz', {})d.setdefault('primary', {}).setdefault('secondary', {}).setdefault('tertiary', {}).setdefault('quaternary', {})

另一個(gè)批評(píng)是setdefault需要一個(gè)新實(shí)例,不管是否使用它。但是,Python(或至少CPython)在處理未使用和未引用的新實(shí)例方面相當(dāng)聰明,例如,它重用內(nèi)存中的位置:

>>> id({}), id({}), id({})(523575344, 523575344, 523575344)

一個(gè)自動(dòng)生動(dòng)的默認(rèn)設(shè)置

這是一個(gè)整潔的實(shí)現(xiàn),在沒有檢查數(shù)據(jù)的腳本中使用與實(shí)現(xiàn)相同的功能__missing__:

from collections import defaultdictdef vivdict():
    return defaultdict(vivdict)

但是,如果您需要檢查您的數(shù)據(jù),使用相同方式填充數(shù)據(jù)的自動(dòng)生動(dòng)的defaultdict的結(jié)果如下所示:

>>> d = vivdict(); d['foo']['bar']; d['foo']['baz']; d['fizz']['buzz']; d['primary']['secondary']['tertiary']['quaternary']; import pprint;
 >>> pprint.pprint(d)defaultdict(<function vivdict at 0x17B01870>, {'foo': defaultdict(<function vivdict 
at 0x17B01870>, {'baz': defaultdict(<function vivdict at 0x17B01870>, {}), 'bar': defaultdict(<function vivdict at 0x17B01870>, {})}), 'pr
mary': defaultdict(<function 
vivdict at 0x17B01870>, {'secondary': defaultdict(<function vivdict at 0x17B01870>, {'tertiary': defaultdict(<function vivdict at 0x17B01870
>, {'quaternary': defaultdict(<function vivdict at 0x17B01870>, {})})})}), 'fizz': defaultdict(<function vivdict at 
0x17B01870>, {'buzz': defaultdict(<function vivdict at 0x17B01870>, {})})})

這個(gè)輸出是相當(dāng)不雅致的,結(jié)果是非常不可讀的。通常給出的解決方案是遞歸地將其轉(zhuǎn)換為DECT,以便進(jìn)行手動(dòng)檢查。這個(gè)非平凡的解決方案是留給讀者的練習(xí)。

性能

最后,讓我們看看性能。我正在減去實(shí)例化的成本。

>>> import timeit>>> min(timeit.repeat(lambda: {}.setdefault('foo', {}))) - min(timeit.repeat(lambda: {}))0.13612580299377441>>>
 min(timeit.repeat(lambda: vivdict()['foo'])) - min(timeit.repeat(lambda: vivdict()))0.2936999797821045>>> min(timeit.repeat(lambda:
  Vividict()['foo'])) - min(timeit.repeat(lambda: Vividict()))0.5354437828063965>>> min(timeit.repeat(lambda: AutoVivification()['foo']))
   - min(timeit.repeat(lambda: AutoVivification()))2.138362169265747

根據(jù)業(yè)績(jī),dict.setdefault效果最好。在您關(guān)心執(zhí)行速度的情況下,我強(qiáng)烈推薦它用于生產(chǎn)代碼。

如果您需要用于交互使用(可能在IPython筆記本中),那么性能并不重要-在這種情況下,我將使用Vividict來獲取輸出的可讀性。與自動(dòng)識(shí)別對(duì)象(該對(duì)象使用__getitem__而不是__missing__,這是為了這個(gè)目的而做的)它要好得多。

結(jié)語

實(shí)施__missing__子類dict設(shè)置和返回一個(gè)新實(shí)例比其他方法稍微困難一些,但是它的好處是

  • 易實(shí)例化
  • 易數(shù)據(jù)總體
  • 容易查看數(shù)據(jù)

因?yàn)樗刃薷母粡?fù)雜和更有效。__getitem__,它應(yīng)該比那種方法更好。

然而,它也有缺點(diǎn):

  • 糟糕的查找將悄悄地失敗。
  • 糟糕的查找將留在字典中。

所以我個(gè)人更喜歡setdefault其他的解決方案,在我需要這種行為的每一種情況下都有。


查看完整回答
反對(duì) 回復(fù) 2019-06-14
?
拉丁的傳說

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個(gè)贊

class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

測(cè)試:

a = AutoVivification()a[1][2][3] = 4a[1][3][3] = 5a[1][2]['test'] = 6print a

產(chǎn)出:

{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}


查看完整回答
反對(duì) 回復(fù) 2019-06-14
?
慕絲7291255

TA貢獻(xiàn)1859條經(jīng)驗(yàn) 獲得超6個(gè)贊

就因?yàn)槲疫€沒見過這么小的,這里有一個(gè)你喜歡嵌套的小塊,沒有汗水:

# yo dawg, i heard you liked dicts                                                                      def yodict():
    return defaultdict(yodict)


查看完整回答
反對(duì) 回復(fù) 2019-06-14
  • 3 回答
  • 0 關(guān)注
  • 1506 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)