突破旧思维
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,当然也可以借助 filter
、 map
等函数):
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同好:我的微博, 我的网站 , 我的知乎专栏 。