於是,我看到了這個問題的三個步驟發生適當的解決辦法:排序,組,格式。
首先,排序將您的輸入排列在邏輯組中。您可以定義一個快速的輔助函數來定義排序關鍵字:
def sorter(netloc):
split = netloc.split('.')
return (split[::-1], -len(split))
正是如此使用它:
data = ['test.sh','api.test.sh','blah.api.test.sh','test.com','api.test.com', 'another.com', 'sub.another.com', 'sub.sub.another.com']
#shuffling data, to show that sorting works
import random
random.shuffle(data)
sorted(data, key=sorter)
Out[14]:
['another.com',
'sub.another.com',
'sub.sub.another.com',
'test.com',
'api.test.com',
'test.sh',
'api.test.sh',
'blah.api.test.sh']
現在,一切都在正確的順序,做一個類似組荷蘭國際集團運作與itertools.groupby
這組由x.y.z.blah.com
的blah.com
部分:
def grouper(netloc):
return ''.join(netloc.split('.')[-2:])
#in-place sort, replicating sorted() call above
data.sort(key=sorter)
from itertools import groupby
[list(g) for k,g in groupby(data, grouper)]
Out[27]:
[['another.com', 'sub.another.com', 'sub.sub.another.com'],
['test.com', 'api.test.com'],
['test.sh', 'api.test.sh', 'blah.api.test.sh']]
末你需要格式這些組合到你想要的層次。這裏是一個快速和骯髒的實現:
def make_hierarchy(groups):
from copy import deepcopy
_groups = deepcopy(groups)
ret = []
for li in _groups:
current = {}
ret.append(current)
while li:
current['name'] = li.pop()
if li:
nxt = {}
current['children'] = nxt
current = nxt
return ret
print(json.dumps(make_hierarchy(grouped), indent=2))
[
{
"children": {
"children": {
"name": "another.com"
},
"name": "sub.another.com"
},
"name": "sub.sub.another.com"
},
{
"children": {
"name": "test.com"
},
"name": "api.test.com"
},
{
"children": {
"children": {
"name": "test.sh"
},
"name": "api.test.sh"
},
"name": "blah.api.test.sh"
}
]
這最後的實施取決於幾個假設,即不會有同組中的任何等效長度netlocs,即sub1.example.com
和sub2.example.com
永遠不會發生。顯然你可以根據需要調整實現。
謝謝!這看起來不錯,我實際上想出了一個類似的方法,所以很高興看到我並不孤單。 – sbrichards 2014-10-31 23:56:50