数据结构优化python将线性元祖转换成字典树的方法,结构优化python,有一个数据表id f
数据结构优化python将线性元祖转换成字典树的方法,结构优化python,有一个数据表id f
有一个数据表
id fid title1 -1 python2 -1 ruby3 -1 php4 -1 lisp5 1 flask6 1 django7 1 webpy8 2 rails9 3 zend10 6 dblog
这是一个栏目表,title 是栏目名称, id 是栏目 id, fid 是栏目的父id.构建一个多级栏目分类
通过 python 查询处理,会得到下面的一个元祖,
t = ( (1, -1, 'python'), (2, -1, 'ruby'), (3, -1, 'php'), (4, -1, 'lisp'), (5, 1, 'flask'), (6, 1, 'django'), (7, 1, 'webpy'), (8, 2, 'rails'), (9, 3, 'zend'), (10, 6, 'dblog'))
希望通过 python 处理,转换成下面的 list 字典树
l = [ { 'id': 1, 'fid': -1, 'title': 'python', 'son': [ { 'id': 5, 'fid': 1, 'title': 'flask', }, { 'id': 6, 'fid': 1, 'title': 'django', 'son': [ { 'id': 10, 'fid': 6, 'title': 'dblog', }, ] }, { 'id': 7, 'fid': 1, 'title': 'webpy', }, ] }, { 'id': 2, 'fid': -1, 'title': 'ruby', 'son': [ { 'id': 8, 'fid': 2, 'title': 'rails', }, ] }, { 'id': 3, 'fid': -1, 'title': 'php', 'son': [ { 'id': 9, 'fid': 3, 'title': 'zend', }, ] }, { 'id': 4, 'fid': -1, 'title': 'lisp', }]
也就是类似网站的目录, 父栏目包含子栏目.
自己写了好几个,感觉效率不够好, 求大神更 pythonic 的方法
在 stackoverflow 有人回答 大概如下:
from pprint import pprintl = []entries = {}for id, fid, title in t: entries[id] = entry = {'id': id, 'fid': fid, 'title': title} if fid == -1: l.append(entry) else: parent = entries[fid] parent.setdefault('son', []).append(entry)pprint(l)
Stackoverflow上的那个答案,要t中的父元素出现在子元素之前,如果不能保证,可以用下面的方式:
from itertools import groupbyfrom operator import itemgetter as getfrom pprint import pprint# group by fidtmp = dict([(k, list(rows)) for k, rows in groupby(sorted(t, key=get(1)), get(1))])def map_fun(row): item = dict(zip(('id', 'fid', 'title'), row)) if row[0] in tmp: item['son'] = find_children(row[0]) return item;def find_children(parent): return map(map_fun, tmp[parent])pprint(find_children(-1))
关于pythonic,可以试试这个
>>> import this
PS:我不是大神啊。
entries[id] = entry = {'id': id, 'fid': fid, 'title': title}
会造成内存暴涨的
我这里先问个问题,查询的元组pid是递增的吗?
也就是说parent = entries[fid]一定是能取到值的呗?
StackOverFlow的大神答案已经很效率了吧。。虽然是错的...如果你的数据是乱序的话,你贴的代码输出的结果就不正确了。
虽然不知道你说的pythonic是啥...如果以看不懂为目的的话,我写了一个...
无论如何,不建议使用这种代码习惯,清晰可读是所有编程的通性,如果为了玩的话,你可以去codeforece上看看各路大神解题的答案。
e, l = {d[0]:{'id': d[0], 'fid': d[1], 'title': d[2]} for d in t}, []for i in e: l.append(e[i]) if e[i]['fid'] == -1 else e[e[i]['fid']].setdefault('son', []).append(e[i])print l
第一行先格式化数据并存储在e中
第二行对e进行遍历,如果e['fid'] == -1 则添加到l数组中。 否则找到对应的e[e[fid]]添加其子节点。
因为l.append(e[i])是地址拷贝,所以e中的数据更改直接影响l的数据(因为都是指向同一个地址的嘛~) 具体细节可以参考我在另外一个问题里面的答案 http://segmentfault.com/q/1010000000397465#a-1020000000397966
以下是上面那个代码的正常版本:
l = []entities= {d[0]:{'id': d[0], 'fid': d[1], 'title': d[2]} for d in t}for e_id in entities: entitiy = entities[e_id] fid = entitiy['fid'] if fid == -1: l.append(entitiy) else: entities[fid].setdefault('son',[]).append(entitiy)print l
编橙之家文章,
相关内容
- Python内建callable函数应用问题,pythoncallable,>Python ha
- 没有Python可以用Sublime text编辑器来运行Py文件吗?,,在一
- Ptyhon gb2312代表什么意思?能表示繁体中文吗,,查了下
- 求Python同时操作多个变量方法,python同时多个变量,题干
- Python替换url内参数值的方式是什么,python替换url内参
- 请问Python Markdown和Markdown2高手们更推荐哪个,markdownm
- python2.7.3 uwsgi安装出错,python2.7.3uwsgi,系统信息:Linux v
- 求问Python归并排序求逆序数方法,python逆序,class nx:
- python django在nginx里模板输出html标签出错,djangonginx,就是
- Python与php在数据处理方面差异有哪些?,python数据处理
评论关闭