• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >编程问答 > python数据结构转换,将线性元祖转换成字典树

python数据结构转换,将线性元祖转换成字典树

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-07

佚名通过本文主要向大家介绍了python元祖,python中元祖,python 创建元祖,python 遍历元祖,python 列表 元祖等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题:python 数据结构转换,将线性元祖转换成字典树
描述:

有一个数据表

id   fid        title
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

这是一个栏目表,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 pprint

l = []
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)

解决方案1:

entries[id] = entry = {'id': id, 'fid': fid, 'title': title}
会造成内存暴涨的

解决方案2:

Stackoverflow上的那个答案,要t中的父元素出现在子元素之前,如果不能保证,可以用下面的方式:

from itertools import groupby
from operator import itemgetter as get
from pprint import pprint

# group by fid
tmp = 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:我不是大神啊。

解决方案3:

我这里先问个问题,查询的元组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


分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • python数据结构转换,将线性元祖转换成字典树

相关文章

  • 2017-06-07 linux命令行和shell脚本编程宝典(shell)命令行显示和不显示输出
  • 2017-06-07 空间创建失败,请您稍后再试!
  • 2017-06-07 七牛云存储中的数据库处理功能支持扩展么?
  • 2017-06-07 (python)请问各位大神,如何在爬虫用post选择该网页的省份变量option并且得到选择该option的网页呢
  • 2017-06-07 java使用current包固定线程池对象,如何动态伸缩?
  • 2017-06-07 用户名包含被系统屏蔽的字符用户名屏蔽字设计
  • 2017-06-07 正则表达式匹配错误
  • 2017-06-07 windows下python控制台输出中文乱码问题?
  • 2017-06-07 html转义字符(laravel)HTML字符串解析显示
  • 2017-06-07 求推荐数据可视化或绘制动画的一些比较系统的教程

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • phplaravel,如何更高效地调试?
    • 这个是redis什么的截图
    • 如何实现根据用户权限显示导航
    • 七牛可以设置文件上传保存名为其md5值而且保留原有后缀
    • 这里好像都是软件的啊,asic在哪?
    • php文件怎么打开PHP中类的封装性是怎么体现出来的?
    • 老吾老以及人之老幼吾幼以及人之幼python命令行传参以及字符串格式化的问题
    • (flask)dbsessioncommit的时候,你会加tryexcept吗
    • 使用MBean服务实现定时任务,部署时出现错误,
    • ValidationofviewstateMACfamac连接不上smtp163com

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有