推导式处理dict

2017-05-04  本文已影响6人  俊杰的笔记
# encoding:utf-8

# 定义一个类Field,含一个实例属性field_name


class Field(object):
    def __init__(self, field_name):
        self.__field_name = field_name  # 双下划线开头的实例属性表示私有
        self.column_type = 'varchar(100)'

    @property  # property注解表示可以用xxx.field_name访问方法,而不是xxx.field_name()
    def field_name(self):
        '提供公有方法访问私有__field_name'
        return self.__field_name


# 现有一个dict,包含一些数据
__data = {
    'a': 'xxx',
    'b': 'yyy',
    'id': Field('user_id'),
    'name': Field('user_name'),
    'email': Field('email')
}


# 需求: 将__data的items中,value的类型为Field的,转换为field_name,返回新的dict
# 最后结果应该是{'id': 'user_id', 'name':'user_name', 'email': 'email'}

# 解法一: 普通写法,最常见的写法
def __answer1(data):
    result = {}
    for k, v in data.items():
        if isinstance(v, Field):
            result[k] = v.field_name
    return result


# 解法二: 使用Java 8的流式处理思想,filter和map组合
# 在java中一次循环中可以先filter再map,但在python中filter和map是两个函数
# 需要遍历两遍
def __answer2(data):
    # 过滤 注意返回值实际是个filter类型的对象,是可迭代的,不需要再list(filtered)一次
    filtered = filter(lambda t: isinstance(t[1], Field), data.items())
    # 转换 注意返回值是个map类型的对象,还需要转换为dict,直接dict(map_obj)转换,不需要先转换为list
    map_obj = map(lambda t: (t[0], t[1].field_name), filtered)
    result = dict(map_obj)
    return result


# 解法三: 使用python强大的推导式,这种解法真正体现python的数据处理思想精髓
# 没有用map, 也没有filter, 也不用lambda
# java的流式处理思想实际不太适合python
def __answer3(data):
    return {k: v.field_name for k, v in data.items() if isinstance(v, Field)}


# 测试
if __name__ == '__main__':
    from time import clock
    start = clock()
    print(__answer1(__data))
    finish1 = clock()
    print(__answer2(__data))
    finish2 = clock()
    print(__answer3(__data))
    finish3 = clock()

    using1 = finish1 - start
    using2 = finish2 - finish1
    using3 = finish3 - finish2
    print(using3 < using2 < using1)
上一篇 下一篇

猜你喜欢

热点阅读