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

根据一个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. 使用BAPISDORDER_GETDETAILEDLIST创建S/4HANA的Outbound Delivery

    要在S/4HANA里创建Outbound Delivery,首先要具有一个销售订单,ID为376,通过事务码VA03查看. 只用61行代码就能实现基于这个Sales Order去创建对应的outbou ...

  2. commons dbcp.jar有什么用

    主流数据库连接池之一(DBCP.c3p0.proxool),单独使用DBCP需要使用commons-dbpc.jar.commons-collections.jar.commons-pool.jar三 ...

  3. PhoneGap实现重力感应

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. java中的泛型1

    1.泛型概述 泛型,即“参数化类型”.一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数 ...

  5. 通过JAVA从MQ读取消息的时候报错及解决

    如果是通过JAVA将消息写入到MQ,再通过JAVA去读取消息,采用MQMessage读消息的方法readUTF()去读取的时候,就不会报错,可以正常读出来.如果采用在MQ资源管理器中插入测试消息或者是 ...

  6. Linux 统计文件夹,文件数量的命令

    用的最多的就是: ls -l | grep "^-" | wc -l ls -l 普通文件就是以 - 开头,文件夹以 d 开头 grep 后面接正则表达式:^- 以 - 开头的匹配 ...

  7. PHP-----CMS

    刚刚看到了一篇关于phpcms的文章自己今后比较有帮助,就把它摘了下来. 1.首先下载phpcms v9的集成安装包并安装,这里就不详细说明了. 2.本地调试建议大家使用APMserver,或者wam ...

  8. HDU 6370 Werewolf 【并查集】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6370 Werewolf Time Limit: 2000/1000 MS (Java/Others)   ...

  9. oracle 通配符及regexp_count函数说明

    通配符 通配符描述示例      %:匹配包含零个或更多字符的任意字符串.WHERE title LIKE '%computer%' 将查找处于书名任意位置的包含单词 computer 的所有书名.  ...

  10. es6之proxy和reflect

    一.proxy //Proxy和Reflect //供应商 let obj={ time:"2017-11-21", name:"net", _r:123 } ...