Python 代码就该是这种味道

作者: 链球选手 | 来源:发表于2016-04-30 09:09 被阅读2468次

每种语言都有自己的味道,而我最喜欢 Python 家的。代码如诗,你可以顺着人类的思维去写代码,既然选择了 Python 大法,就应该像 Pythonista 那样思考,写出 Pythonic 的代码,这篇文章介绍的都是很简单很基本的技巧,但也正是这些基础的用法使得 Python 变得与众不同。

Life is short, you need Python

行内判断

求绝对值
Non-pythonic version

# Non-pythonic, ugly
if x < 0:
    y = -x
else:
    y = x

Pythonic version

#Pythonic, elegant
y = -x if x < 0 else x

快速交换

交换两个变量的值
Non-pythonic version

# Non-pythonic, ugly
temp = x
x = y
y = temp

Pythonic version

#Pythonic, elegant
x, y = y, x

快速生成数组

找出数组中所有大于零的数?

Non-pythonic version

# Non-pythonic, ugly
x_list = [1, -1, 2, 3, -4]
y_list = []
for x in x_list:
    if x > 0:
        y_list.append(x)

Pythonic version

#Pythonic, elegant
x_list = [1, -1, 2, 3, -4]
y_list = [x for x in x_list if x > 0]

不只是数组,字典也可以快速生成:

#Pythonic, elegant
x_list = [1, -1, 2, 3, -4]
x_dict = {str(x): x for x in x_list}

列表切片

想要获取列表中第 3-5 个元素?

Non-pythonic version

# Non-pythonic, ugly
alist = [1, 2, 3, 4, 5, 6, 7]
blist = []
index = 0
for x in alist:
  if 2 < index < 6:
    blist.append(x)
  index += 1

Pythonic version

#Pythonic, elegant
alist = [1, 2, 3, 4, 5, 6, 7]
blist = alist[3:6]

切片还有很多其他用法,可以戳这里了解更多。

简化判断

Non-pythonic version

# Non-pythonic, ugly
if x == 1 or x == 2 or x ==3 or x == 4:
    print(x)

Pythonic version

#Pythonic, elegant
if x in [1, 2, 3, 4]:
    print(x)

获取序号

Non-pythonic version

# Non-pythonic, ugly
i = 0
for x in x_list:
    print(i, x)
    i += 1

Pythonic version

#Pythonic, elegant
for index, x in enumerate(x_list):
    print(index, x)

只要 x_list是可以迭代的对象就行,enumerate()还可以接受一个参数来指定序号的初始值:
for index, x in enumerate(x_list, 1) 指定起始序号为1。

Counter来计数

还在手动计数?

# Non-pythonic, ugly
x_list = ['Ozil', 'Ramsey', 'Ozil', 'Ramsey', 'Giroud']
x_dict = {}
for x in x_list:
    if x in x_dict.keys():
        x_dict[x] += 1
    else:
        x_dict[x] = 1
print(x_dict)

试试Counter

#Pythonic, elegant
from collections import Counter

x_list = ['Ozil', 'Ramsey', 'Ozil', 'Ramsey', 'Giroud']
x_dict = Counter(x_list)
print(x_dict)
巧用函数工具

这里介绍两个常用的 Python 函数工具,map,reduce, 体会函数式编程的快感。

比如我有一大堆英文名,书写不规范,要求你整理成规范的形式(首字母大写,其余小写),这个例子来源于廖老师的Python教程中的习题

Non-pythonic version

# Non-pythonic, ugly
name_list = ['luccy', 'BaTT', 'bOunD']
for name in name_list:
    name = name[0].upper()+ name[1:].lower()
    print(name)

觉得上面的代码还行,不算丑陋?让我们换个思路,用 mapmap()函数接收两个参数,一个是函数,一个是Iterable(可迭代对象),map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

Pythonic version
谢谢 @想成为会写代码的biologi 提醒 Python 有现成的 string.capitalize()函数:

#Pythonic, elegant
def normalize(name):
    return name.capitalize()

name_list = ['luccy', 'BaTT', 'bOunD']
print(list(map(normalize, name_list)))

再来思考这个问题,给你一个列表,求出列表中所有元素的积(还是来自于廖老师的博客)

Non-pythonic version

# Non-pythonic, ugly
alist = [1, 3, 6, 10]
product = 1
for x in alist:
  sum *= x

对于这种问题,其实我们完全可以用reduce来解决,reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

就让我们把这个求积的过程用reduce()来解决吧:
Pythonic version

#Pythonic, elegant
def prod(alist):
    return reduce(multi, alist)

def multi(x, y):
    return x * y

alist = [1, 3, 6, 10]
print(prod(alist))

相关文章

网友评论

  • cc03cfd9c25f:最近想学点GUI,看到你的PyQt5笔记过来的
  • cc03cfd9c25f:行内判断不服,应该减少使用,绝对值直接abs(-1)不就行了。map的例子不服,任何比较复杂的函数应该避免使用map,改成生成式或者列表推导式

    我就是要挑骨头 :stuck_out_tongue_closed_eyes:
    链球选手:@Lyon0804 列表推导确实更能体现 Python 的特点,我也建议在大多数情况下都使用列表推导替代 map,绝对值只是举个例子。。。
  • 8093872cc820:更简单的方法:
    首字母大写现成的function: string.capitalize()

    求乘积:reduce(lambda x,y: x*y, alist)
    链球选手:@想成为会写代码的biologi 感谢补充,首字母那个我确实没想到`string.capitalize()`,求乘积那个我是觉得初学 Python 的未必知道 `lambda`, 写成函数更容易懂一点。
  • 长风四爷:初学,期待更多好文章
    链球选手:@长风四爷 谢谢关注~~
  • 5c655fa10539:漂亮
    链球选手:@沐蓝地 嘿嘿嘿,谢谢回复~~
  • 465826ec6f26:没用过py,但是这些函数底层的实现是不是就是你认为的那些丑陋的代码?其实其他语言也提供更高层次的封装,我觉得都差不多
    链球选手:@CHEN川 你说的有一定道理,但我认为不全对。
    这些函数底层的实现是不是就是你认为的那些丑陋的代码?
    --不是的,至少不全是。那个行内的 `if else`内部实现估计也就是其他语言平常用的方式,只是起到精简代码的作用;但很多 Python 外表优雅的语法内部实现也很高效,比如说`map()`和`reduce()`(映射和归纳),对于列表中的每一个元素都是独立操作的,也就是说可以并行处理,这在对大数据的处理上优势明显,有兴趣可以看一下 Google 关于 MapReduce 的论文:http://research.google.com/archive/mapreduce.html;其他的像列表推导等操作效率上实实在在比“丑陋”的写法更高。
    --退一步说,即使这些外表优雅的操作不能提高运行效率,但至少提高了写代码的效率,有多少人用 Python 是因为它的运行效率高?多是看中了它的开发效率和“优雅”罢了;

    其实其他语言也提供更高层次的封装,我觉得都差不多。
    --我觉得差多了!世界上有这么多编程语言,我们选择语言解决具体问题的时候,关键不在于能不能,而在于合不合适,就像 Python 虽然可以做数值计算,但是我不会用它去做计算量巨大的事情,因为不合适!

    感谢回复~~
  • 向日葵的笑:最爱py真的很舒服
    链球选手:@抹茶与橙汁 Python 大法好
  • 水蓝木安:😳
    链球选手:@木又少火 嘿嘿嘿
  • e9c546a5ead7:Python果然强大!
    链球选手:@TonyTsui Python 大法好!
  • biubiutoo:java程序员就看看
    链球选手:@biubiutoo 嘿嘿嘿,Java 大法好 :wink:
  • 妤和:不服!!!不服!!!
  • 52e3d784fc07:我也喜欢他家的,一句顶好几句,不过劣势同样明显唉。
    家中古词:@陌上青草 你提到的劣势是指哪方面?
  • 秋桥Stacy:最近接触到python,每次学到一个新方法,都觉得,哇塞,好神奇,好好用。然后我就开始找网站多练习python了。
    链球选手:@秋桥Stacy 是哒,Python 有一种让人相见恨晚的感觉
  • 4a53bf1ae933:编写高质量代码 改善Python程序的91个建议
  • adminlzzs:最后一个不错,学到了
    adminlzzs:@Cescfangs 同乐!
    链球选手:@adminlzzs 五一快乐~~
  • 5b674470f1cd:涨姿势…:+1:
    链球选手:@混江龙 嘿嘿嘿,谢谢你的回复 :relieved:
  • 妤和:你宝宝我堵在高速上 而你 在这里发代码:unamused:
    biubiutoo:@Cescfangs 哈哈哈:smile:(请允许我在这里哈哈哈)
    妤和:@Cescfangs 路上小心 不要玩手机
    链球选手:@妤和 我也准备出发了💪🏾💪🏾💪🏾

本文标题:Python 代码就该是这种味道

本文链接:https://www.haomeiwen.com/subject/qjdkrttx.html