专栏首页PyStaDataPython | 优雅的列表推导式

Python | 优雅的列表推导式

提出问题

  • 生成 1-20 的列表 a
  • 挑出列表 a 中偶数,存为列表 b
  • 将列表 b 的所有元素平方,生成列表 c

分析问题

采用 for 循环,加条件判断,很轻松就可以实现。但有没有更简洁的实现方式?列表推导式(List Comprehension)。对比看看两者的效果。

实现过程

for 循环

# 生成列表
a = []
for i in range(20):
    a.append(i)

# 条件判断
b = []
for i in a:
    if i % 2 == 0:
        b.append(i)

# 计算
c = []
for i in b:
    c.append(i**2)

# 结果展示
print(a)
print(b)
print(c)

# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]

列表推导式

a = [i for i in range(20)]
b = [x for x in a if x % 2 == 0]
c = [x**2 for x in b]

# 结果展示
print(a)
print(b)
print(c)

# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]

二者比较

语法

对比两段实现代码,语法差异一目了然。用 forif 语法如下:

for (set of values to iterate):
    if (conditional filtering):
        output_expression()

写作列表推导式如下:

 [ output_expression() for(set of values to iterate) if(conditional filtering) ]

速度

Do you know List Comprehensions are 35% faster than FOR loop and 45% faster than map function? (AARSHAY JAIN, JANUARY 19, 2016)

import timeit
#  for 循环
def gen_lst(n):
    lst = []
    for i in range(n):
        lst.append(i)
    return lst

for_loop = timeit.timeit(stmt="gen_lst(1000)",
                         setup="from  __main__ import gen_lst", number=100000)
# stmt 需要测试的函数或语句,字符串形式
# setup 运行的环境,本例子中表示 if __name__ == '__main__':
# number 被测试的函数或语句,执行的次数,本例表示执行100000次 gen_lst()。默认是10000次
# 所以,此函数表示在if __name__ == '__main__'的条件下,执行100000次gen_lst()消耗的时间

# 列表推导式
lst_comp = timeit.timeit(stmt="[x for x in range(1000)]",
                         setup="from  __main__ import gen_lst", number=100000)  # 4.470719099999769

print("for循环耗时:{}\n列表推导式耗时:{}".format(
    for_loop, lst_comp))

# for 循环耗时:8.945164900000002
# 列表推导式耗时:4.339412200000002

为什么列表推导式比 for 循环更快呢?这是由字节码决定的。在 for 循环中先要加载 append 方法,然后再执行后续运算;而列表推导式则直接调用了 LIST_APPEND 命令来添加元素。就是这个区别使列表推导式比循环更快,当嵌套多层循环和判断的情况下对比更明显。

实现 for 和 map() 函数

# 需求:将列表所有元素除以 10
lst = [100,1000,10000,100000]

# for 循环
new_lst = map(lambda x:x/10,lst)

# 列表推导式
new_lst = [x/10  for x in lst]

列表推导式的应用

拉平矩阵

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

# for 循环
flattened = []
for row in matrix:
    for i in row:
        flattened.append(i)

# 列表推导式
flattened = [i for row in matrix for i in row]  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

矩阵转置

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

# for 循环
transposed = []
for i in range(3):
    trans_row = []
    for row in matrix:
        trans_row.append(row[i])
    transposed.append(trans_row)


# 列表推导式
transposed = [[row[i] for row in matrix] for i in range(3)]

# NumPy
import numpy as np
arr = np.array(matrix)
arr.T

小结

本文由最简单的列表生成和计算入手,比较了 for 循环和列表推导式的语法和速度等方面的特点,并展示了列表推导式的运用。其实列表推导式还有更多的应用,有兴趣可以阅读这份 Tutorial[1]

总体来看,列表推导式比 for 循环更简洁和优雅,而且速度更快。但列表推导式写起来爽,读起来并不爽,代码的可读性没有用循环清晰。所以在使用列表推导式的时,需要注意代码的可读性。

在《流畅的 Python》中,作者建议通常的原则是,只用列表推导式来创建新的列表,并且尽量保持简短。如果列表推导式的代码超过了两行,看是否考虑用循环重写。用循环还是列表推导式和创作文章一样,没有硬性的规定,但要自己把握好度。

参考资料

[1]

Tutorial – Python List Comprehension With Examples: https://www.analyticsvidhya.com/blog/2016/01/python-tutorial-list-comprehension-examples/

本文分享自微信公众号 - PyStaData(gh_60f259052905),作者:mudaozzz

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 文件管理工具Zotero入门介绍

    Zotero 是一款开源免费的文献管理软件,作为 Firefox 浏览器插件起家,在浏览器文献智能导入、PDF 元数据抓取方面具有优势。使用一段时间之后,发现用...

    PyStaData
  • Stata | 2020年国家社科基金立项名单分析

    刚在群里看见今年社科基金立项名单,想着了解下学科、单位和课题名称的情况,所以用 Stata 整理和粗略分析了一下。用表格贴入公众号太长,不便于浏览,所以表格中就...

    PyStaData
  • 中微笔记 | 03_偏好

    完备性:指任何两个消费束都是可比较的。反身性:任何消费束至少与本身同样好。传递性:指假如消费者认为

    PyStaData
  • 实操指南|关于Python中的列表理解

    列表理解通常在Python中用于编写单行语句,这些语句通过循环访问可迭代对象来创建新列表或字典。本文将首先介绍有关for循环在Python中的工作原理,然后说明...

    用户6543014
  • 【Python 第25课】 初探list

    昨天课程里的例子有点没说清楚,有同学表示写在程序里发生了错误。因为我当时写这个代码片段时,心里假想着这是在一个函数的内部,所以用了return语句。如果你没有把...

    Crossin先生
  • 大数据让你必须知道的十一旅游趋势

    编者按: 假日办撤了,“黄金周长假”到底意味着什么?官方数据可能太宏大,不妨借用新兴社交媒体的大数据,观察和记录2014年“十一”黄金周。看看游客从哪里来,...

    小莹莹
  • 【python】编程语言入门经典100例

      1 # 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

    py3study
  • 多人游戏

    王兵
  • python简单脚本之概率计算

    py3study
  • 如何隐藏SAP CRM WebClient UI配置页面的字段

    In UI component workbench, we can see lots of fields under column “Available Fie...

    Jerry Wang

扫码关注云+社区

领取腾讯云代金券