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

根据一个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. nfs 笔记

    问题:客户端在nfs文件目录下读写文件提示Permission denied: 解决方法: 修改/etc/exports 中 文件共享方式为 no_root_squash no_root_squash ...

  2. 用CI框架向数据库中实现简单的增删改查

    以下代码基于CodeIgniter_2.1.3版 用PHP向数据库中实现简单的增删改查(纯代码)请戳 http://www.cnblogs.com/corvoh/p/4641476.html Code ...

  3. 指数循环节&欧拉降幂

    证明:https://www.cnblogs.com/maijing/p/5046628.html 注意使用条件(B的范围) 例题: FZU1759 HDU2837 ZOJ1674 HDU4335

  4. JAVA二叉树递归构造、二叉树普通遍历及递归遍历

    二叉树类: package com.antis.tree; public class BinaryTree { int data; //根节点数据 BinaryTree left; //左子树 Bin ...

  5. JAVA JAVA面试题和项目面试核心要点精华总结(想进大公司必看)

    http://blog.csdn.net/ourpush/article/details/53706524 1.常问数据库查询.修改(SQL查询包含筛选查询.聚合查询和链接查询和优化问题,手写SQL语 ...

  6. HDU 2086 P - A1 = ?(推表达式)

    传送门:http://acm.geekxiong.tech/vjudge/contest/view.action?cid=14#problem/P P - A1 = ? Time Limit:1000 ...

  7. TCP-IP Architecture and IP Packet

    Why Internet working? To build a "network of networks" or internet. operating over multipl ...

  8. 使用nuget过程中一些问题总结

    更新System.Web.Http组件以及其相关依赖项使用以下命令更新: Update-Package Microsoft.AspNet.WebApi –reinstall 如果没有这个引用,则先添加 ...

  9. 360极速浏览器用ie8模式打开网页(360浏览器同理)

    在访问年代久远的的网页时经常会遇到兼容性的问题,用360浏览器(或360极速浏览器)中通过设置可解决. 在360极速浏览器中分别依次选择:选项->高级设置->内核模式->内核切换设置 ...

  10. 前端ajax的各种与后端交互的姿势

    前端中常常用的与后端交换数据的话,通常是要用到ajax这种方法的 但是交互的方式有很多种,很多取决于你后端的属性,我这儿主要列举我目前项目比较常用的两种方式 --一个是我们通用的web api和控制器 ...