突破旧思维
2017.01.07 21:00:59

两则Python方面的例子。

第一则。看了不少别人的代码,发现大量Python程序员习惯这么取List里的数据:

lst = [['张三丰', '太极拳', '武当派', ['男', 60]],
       ['越阿青', '越女剑', '无门派', ['女', 15]],
       ['凌未风', '大须弥', '天山派', ['男', 48]],
       ['张无忌', '九阳功', '武当派', ['男', 28]],
       ['铁摩勒', '八仙剑', '昆仑派', ['男', 35]]]

for l in lst:
    # 处理l
    print(l[0], l[1], l[2], l[3][0], l[3][1])

这种涉及位置的处理方式,一旦逻辑复杂起来,或则数据多了,代码就变得难以阅读,甚至久而久之自己再看都费劲。

我们可以换一种方式:

for name, kf, pai, (s, age) in lst:
    # 处理l
    print(name, kf, pai, s, age)

这里利用了解构特性,方法更一目了然了。如果要操作原lst列表,则可以这样做(借助enumerate()):

for idx, (name, kf, pai, (s, age)) in enumerate(lst):
    # 处理l
    if pai == '无门派':
        lst[idx][2] = '越女派'

或者使用列表解析(List Comprehension,当然也可以借助filtermap等函数):

lst = [[name,
        kf,
        '越女派' if pai == '无门派' else pai,
        [s, age]] for name, kf, pai, (s, age) in lst]

事情感觉是一步步变好。但是不是还有继续改进的空间呢?比如lst数据列表?可能很多人会喜欢设计一个数据类/数据集合类,举个例子(第二则):

class Data:
    def __init__(self,  name, kf, pai, props):
        self.name  = name
        self.kf    = kf
        self.pai   = pai
        self.props = props


class DataSet:
    def __init__(self):
        self.dataSet = []

    def append(self, item):
        self.dataSet.append(item)


d1 = Data('张三丰', '太极拳', '武当派', ['男', 60])
ds = DataSet()
ds.append(d1)
ds.dataSet[0].name

但如果只是一个数据模型,而且数据生成好后只用于查询,则大可使用collections.namedtuple函数,这是一个工厂方法,能够生成一个tuple的增强子类:

from collections import namedtuple

DM = namedtuple('DataModel', 'name, kf, pai, props')
d1 = DM('张三丰', '太极拳', '武当派', ['男', 60])
ds.append(d1)
ds.dataSet[0].name

这不是更方便吗?

上面只是大概举两个例子,还可以继续根据现实所需优化结构:如果需要各种复杂数据操作,则可继续丰富Data类的方法;如果只是涉及简单的操作,则可以考虑Map。但希望能体现出充分借助语言特性进行代码良好构造的重要性。

Python发展到今天,已不能简单理解早十几年提出的“统一一种方式”的理念了,找出最优方式而坚持并形成约定,应该是这个理念的深入含义。

现在市面上的Python书籍琳琅满目,但如果只是裹足于常规使用,确实很容易陷入所谓“Python容易”的感觉中。但其实Python并不容易,什么语言都不容易,要娴熟掌握都是要不断磨练。

这一段常看到“给语言排难易度”、“这个语言好还是那个语言好”、“谁又取代了谁”之类的话题,其实静下心来充实自己就好了。

很多的思维,不仅仅是编程方式,还有看问题的角度,我们都需要不时提醒自己:要不断尝试突破旧思维,突破思维禁锢,让自己的头脑中始终存在着一条清晰的主轴。这样才能把握好方向。

我是程序员2gua,现在写Python,愿意结交Python同好:我的微博我的网站我的知乎专栏


(0)

发表评论请先登录或注册