簡體   English   中英

具有單個列表中的嵌套類別的字典

[英]Dictionary with nested categories from a single list

我有一個列表,其結構如下:

arr = [ ['a'],
                ['a','b'],
                ['a','x','y'],
                ['a','c'],
                    ['a','c','a'],
                    ['a','c','b'],
                        ['a','c','b','a'],
                        ['a','c','b','b'],
                ['a','d'],
            ['b'],
                ['b','c'],
                    ['b','c','a'],
                    ['b','c','b'],                  
            ['c','d'],
                ['c','d','e'],
                ['c','d','f'],
                    ['c','d','f','a'],
                    ['c','d','f','b'],
                        ['c','d','f','b','a'],
                ]

正如您將觀察到列表具有一些獨特元素,然后以下元素構建在唯一元素上,直到出現新的唯一元素。 這些應該屬於類別和子類別。 所以[a],[b],['c','d']是廣義的主要類別,然后在基於與上述相同的原則的子類別中還有其他子類別。 理想情況下,我希望將類別和子類別作為字典。 最終結果應該類似於:

{'a': ['a-b',
     'a-x-y',
     {'a-c': 
           ['a-c-a',
            {'a-c-b':
                    ['a-c-b-a', 
                     'a-c-b-b']
            }]
     }
    ],
'b' : ................
'c-d': ...............}

我也可能只使用第一級子分類並完全丟棄其余部分。 在這種情況下,輸出將是:

{'a': ['a-b', 'a-x-y', 'a-c', 'a-d'], 'b': ['b-c'], 'c-d': ['c-d-e', 'c-d-f']}

我已經為第二個場景編寫了代碼,但我不確定這是否是解決此問題的有效方法:

def arrange(arr):
cat = {"-".join(arr[0]): ["-".join(arr[1])]}
main = 0
for i in range(2,len(arr)):
    l = len(arr[main])
    if arr[main] == arr[i][0:l]:
        cat["-".join(arr[main])].append("-".join(arr[i]))
    else:
        cat["-".join(arr[i])] = []
        main = i
for k,v in cat.items():
    found = True
    i = 0
    while i < len(v)-1:
        f_idx = i + 1
        while  v[i] in v[f_idx]:
            v.pop(f_idx)
        i += 1
return cat

輸出 - :

{'a': ['a-b', 'a-x-y', 'a-c', 'a-d'], 'b': ['b-c'], 'c-d': ['c-d-e', 'c-d-f']}

請幫助我更好地編寫這些代碼,或者幫助我使用具有完整結構的字典,其中包含所有子分類。 謝謝

最后,我相信我所描述的是第一級子分類並完全丟棄其余部分。

訣竅是根據列表中的項目(鍵)何時不是后續項目(值)的子列表來創建操作。
使用相同的邏輯來刪除重復項。

from collections import defaultdict

#Function that compares two lists even with duplicate items
def contains_sublist(lst, sublst):
    n = len(sublst)
    return any((sublst == lst[i:i+n]) for i in xrange(len(lst)-n+1))

#Define default dict of list
aDict = defaultdict(list)
it = iter(arr)

#Format key 
key = '-'.join(next(it))
s = list(key)

# Loop that collects keys if key is not sublist else values
for l in it:
    if contains_sublist(l, s):
        aDict[key].append(l)
    else:
        key = '-'.join(l)
        s = l

#Loop to remove duplicate items based upon recurrance of sublist
it = iter(aDict.keys())
for k in it:
    dellist = []

    for s in aDict[k]:
        for l in aDict[k]:
            if l != s:
                if contains_sublist(l, s):
                    if not l in dellist:        
                        dellist.append(l)
    for l in dellist:        
        try:
            aDict[k].remove(l)
        except ValueError:
            pass

#Create final dict by concatenating list of list with '-'
finaldict = {k:[ '-'.join(i) for i in v ] for k,v in aDict.iteritems()}

結果:

Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>> 
>>> finaldict
{'a': ['a-b', 'a-x-y', 'a-c', 'a-d'], 'b': ['b-c'], 'c-d': ['c-d-e', 'c-d-f']}
>>> 

你在描述一個Trie

這是一個非常基本的實現:

def make_trie(words):
   root = dict()
   for word in words:
       current_dict = root
       for letter in word:
           current_dict = current_dict.setdefault(letter, {})
       current_dict[1] = 1
   return root

trie = make_trie(arr)
print(trie)
# {'a': {1: 1, 'c': {'a': {1: 1}, 1: 1, 'b': {'a': {1: 1}, 1: 1, 'b': {1: 1}}}, 'b': {1: 1}, 'd': {1: 1}, 'x': {'y': {1: 1}}}, 'c': {'d': {1: 1, 'e': {1: 1}, 'f': {'a': {1: 1}, 1: 1, 'b': {'a': {1: 1}, 1: 1}}}}, 'b': {1: 1, 'c': {'a': {1: 1}, 1: 1, 'b': {1: 1}}}}
print(trie.get('a',{}).get('x',{}))
# {'y': {1: 1}}

這個trie只是嵌套的dicts,所以很容易迭代['a', 'x']所有子元素,或者選擇所有最大深度為2的dicts。

1用於葉字:例如,如果您將['a', 'x', 'y']作為子數組,而不是['a', 'x']

Python有更完整的Trie庫,例如pygtrie

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM