项目中有可能会碰到这样一种场景:

根据一个id,查询得到和id对应的完整数据信息存储对象,比如书籍id到书籍详细信息,用户id到用户详细信息等,详细信息字段可能包括几十甚至上百个数据字段,真正需要返回给调用方的字段实际上却只占其中一小部分,这是出于性能和带宽的考虑(甚至在有些场景中,处于隐私或者安全考虑,强制要求不能返回非协议定义的信息字段,比如第三方登录一般只返回用户昵称、性别等少量信息),一般会从详细的数据对象中抽取出所需要的信息组装一个新的简化对象。

今天碰到这样一个问题,需要将一个存储多个详细信息对象的list转化为一个简化对象的list返回给主调方,尝试了数种方法后,通过使用列表推导、字典推导以及getattr内置函数这三者,用数行代码即达到了这一目的,

原始数据结构定义:

class detail_info(object):
def __init(self):
self.id = ''
self.title = ''
self.name = ''
self.url = ''
self.avatar = ''
self.p1 = None
self.p2 = None
self.p3 = None
self.p4 = None
self.p5 = None
self.p6 = None
self.p7 = None
self.p8 = None
...

实际所需要返回的信息字段为id,title,url和p1,放入一个字典即可,如下为针对一个长度为5的list执行的结果,经过字典推导+列表推导,并通过getattr动态获取类的属性值,两行代码即实现了将所需字段抽取出来形成一个以dict为元素的list。

>>> needed_keys = ['id', 'title', 'url', 'p1']
>>> [{k: getattr(x, k) for k in needed_keys} for x in alist]
[{'url': 'url_0', 'p1': 'p1_0', 'id': 'id_0', 'title': 'title_0'}, {'url': 'url_1', 'p1': 'p1_1', 'id': 'id_1', 'title': 'title_1'}, {'url': 'url_2', 'p1': 'p1_2', 'id': 'id_2', 'title': 'title_2'}, {'url': 'url_3', 'p1': 'p1_3', 'id': 'id_3', 'title': 'title_3'}, {'url': 'url_4', 'p1': 'p1_4', 'id': 'id_4', 'title': 'title_4'}, {'url': 'url_5', 'p1': 'p1_5', 'id': 'id_5', 'title': 'title_5'}]

如果要直接返回一个类似如下的简化结构:

class SimpleInfo(object):
def __init__(self):
self.id = ''
self.title = ''
self.url = ''
self.p1 = None

也只需要预先定义一个和alist等长的存储SimpleInfo结构的等长blist,组合zip函数的使用,稍加改动即可:

>>> blist = [SimpleInfo() for i in range(0, len(alist))]
>>> needed_keys = ['id', 'title', 'url', 'p1']
>>> [[setattr(y, k, getattr(x, k)) for k in needed_keys] for x, y in zip(alist,blist)]
[[None, None, None, None], [None, None, None, None], [None, None, None, None], [None, None, None, None], [None, None, None, None]]

 >>> blist[0].__dict__
 {'url': 'url_0', 'p1': 'p1_0', 'id': 'id_0', 'title': 'title_0'}

这里列表推导的代码使用setattr对blist中的SimpleInfo对象属性赋值,由于函数返回值为None,所以列表推导的结果是一个元素为None的list,通过查看blist[0]的信息,可以确认实际要赋值的属性已经通过setattr赋值给blist中对应的对象了。

python中利用少量代码快速实现从类对象中抽取所需属性的一种实践的更多相关文章

  1. Myeclipse中把java代码导成UML类图

    Myeclipse中把java代码导成UML类图 1.右键点击项目名称,选择New-------àUML2 Model 2.给类图命名 3.导成类图 1)如果要把整个项目导成类图,则把整个项目拖到类图 ...

  2. SpingMVC中利用BindingResult将错误信息返回到页面中

    SpingMVC中利用BindingResult将错误信息返回到页面中. ActionFrom中: private String name; private String password; get( ...

  3. java中,方法可以访问他的类对象的任何私有特性

    java中,方法可以访问他的类对象的任何私有特性 读一本书(Core Java for the Impatient)时,发现这个注意,以前的时候没有在意,今天仔细想想发现记忆不深刻.记录一下 下面代码 ...

  4. class中new与未new的区别 类对象占用空间--转载

    转载自http://blog.sina.com.cn/shuiwuhendeboke    颗颗的博客 (1)作用域不同 不用new:作用域限制在定义类对象的方法中,当方法结束时,类对象也被系统释放了 ...

  5. WPF中利用后台代码实现窗口分栏动态改变

    在WPF中实现窗口分栏并能够通过鼠标改变大小已经非常容易,例如将一个GRID分成竖排三栏显示,就可以将GRID先分成5列,其中两个固定列放GridSplitter. <Grid Backgrou ...

  6. 用python将项目中的所有代码(或txt)合并在一个文件中

    设计模式开卷考试给的例子代码都是一个类一个java,实在太恶心了,所以写了一个python脚本. import os fileansdir=r'C:\Users\tonyson_in_the_rain ...

  7. Python的高级特性8:你真的了解类,对象,实例,方法吗

    Python的高级特性1-7系列是本人从Python2过渡3时写下的一些个人见解(不敢说一定对),接下来的系列主要会以类级为主. 类,对象,实例,方法是几个面向对象的几个基本概念,其实我觉得很多人并不 ...

  8. 在pycharm中自定义模板代码,快速输出固定代码块

    pycharm中有时会经常输出固定一段代码,为避免每次重复输入,可以自定义一段模板代码,请看以下图教程: 1.  点击 file   里面的   setting 2. 在搜索框输入live,就会显示出 ...

  9. jsp中利用java代码换行

    从数据库中取出的10条商品数据分两行显示,每行5条. <% for(int i=0; i<latestProducts.size(); i++) { Product p = latestP ...

随机推荐

  1. 020hashlib模块

    #里面内容没有见过,可能会比较难懂,需要找资料.我只是记录了视频中的用法,其他理解的东西,我直接理解,就没有写下来了.下面内容是视频演示过程 import    hashlib m = hashlib ...

  2. SOJ4478 Easy Problem II(模拟、栈)

    Time Limit: 3000 MS Memory Limit: 131072 K Description 在数据结构中 我们学习过 栈 这种数据结构 通过栈 我们可以将1,2,3,...,n转化成 ...

  3. Java---页面之间传值跳转

    从首页A进入页面B,然后从B页面登录,成功后跳转到A页面,并打印一句话“登录成功”,传值需要用的后台的. 在B页面写: <%     session.setAttribute("key ...

  4. python2.7 安装Django

    目前Django最新版是2.0,不支持Python2,在使用pip 安装的时候会报错,pip默认安装的是最新的稳定版本 使用pip指定安装的版本:pip install django==1.11.4 ...

  5. MFC中用户自定义类响应自定义消息

    这篇技术文章不是讨论经典的MFC中的消息工作机理的,讨论消息工作原理.方式和路径的文章在网上和书本中随处可见.网上众多的讨论都是关于如何响应并进行用户自定义消息映射的:网上还有一些文章介绍如何在自定义 ...

  6. HDU 1789 Doing Homework again(非常经典的贪心)

    Doing Homework again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  7. OSD仿真_MFC程序01

    Windows系统具有强大的绘图功能,可以用来模拟OSD显示.接下来将设计一个简单的模拟显示终端的程序,用于后续显示功能和菜单系统的开发.说明一下,对于Windows下的MFC编程我不怎么了解,只知道 ...

  8. linux 内存操作相关命令

    清理内存 echo 1 > /proc/sys/vm/drop_caches 查看内存使用情况 free –m 查看内存条数命令: dmidecode |grep -A16 "Memo ...

  9. js中两个日期大小比较,获取当前日期,日期加减一天

    一.两个日期大小比较 1.日期参数格式:yyyy-mm-dd // a: 日期a, b: 日期b, flag: 返回的结果 function duibi(a, b,flag) { var arr = ...

  10. mysql 配置安装

    1.     下载: mysql-5.7.20是解压版免安装的,mysql-5.7.20下载地址:http://dev.mysql.com/downloads/mysql/ 直接下载,无需注册和登录. ...