Python 之List Comprehension基础语法教学

何谓List Comprehension


这个功能是以一个特别的方式应用for回圈,并创造出带有元素的List。
应用List Comprehension,除了程式码比较好看,执行效率其实也比较高喔!

情境题

好的,在体验List Comprehension的威力之前,先来用比较基本的方式来产生List。
请创造一个含有整数0~9的List。
请用for回圈,不要写10行...

如果你有好好练习前几天的语法,你的程式应该会像这样:

arr1 = []

for i in range(10):
    arr1.append(i)

print(arr1)

使用List Comprehension

好的,就让我们来看看List Comprehension会怎么做!
我们就来创造一个跟上述一样,含有整数0~9的List。

范例:

# in-place construction
arr1 = [i for i in range(10)]

print(arr1)

你看看,一行就解决,是不是让人很心动呢!
这边来解释一下,这行程式码要怎么读& 理解。
这行是说我们要创造一个List arr1
里面要放什么? 要放变数i
变数i哪里来? 从后面的for回圈来
那for回圈会从range拿出什么呢? 是0~9
于是我们就得到一个含有0~9的List啦!

变化型List Comprehension

除了单纯的从for回圈取得元素之外,List Comprehension还有很多变化型可用

话不多说,范例来:

# in-place construction
arr1 = [i for i in range(10)]

# you can use if to filter the elements
arr2 = [x for x in arr1 if x % 2 == 0]

# you can use as many conditions as you want!
arr3 = [x for x in arr1 if x >= 3 and x % 2]

# use nested for loops to make everyone dizzy XD
arr4 = [(x, y) for x in range(3) for y in range(4)]

print(arr1)
print(arr2)
print(arr3)
print(arr4)

好的,又到了程式码解释时间,事情是这样的:
第二个List Comprehension,我们加上了if条件。
arr2要放什么? 放x
x怎么来,从后面的for来。
for从啥提取元素? 从arr1
有什么过滤条件吗? 取出的元素至少要通过除以2的余数为0 (即为2的倍数)
于是我们从arr1取出0~9,把为2的倍数的元素存入arr2,故答案为0, 2, 4, 6, 8
其实这样的写法就等于告诉Python,要在for回圈内包一层if的意思。

第三个List Comprehension,我们用上了多个条件。
但其实基本概念与第二个很像,除了条件变多以外,没什么大改变,故不多做解释。

第四个List Comprehension,我们用了两个for回圈。
那就跟刚刚说的一样,我们可以想像成第一层for回圈里面又包了一个for回圈。
那就来考考各位,请问arr4里面总共会有几个元素啊?

答案是12个,你猜对了吗?

List Comprehension的效率

如先前所说,List Comprehension除了在语法上比较简洁优美以外,效率上也是赢过传统的方式。
让我们看看以下范例:

import time

arr1 = []
s = time.time()
for i in range(int(1e+6)):
    arr1.append(i)
print('took {} secs'.format(round(time.time() - s, 3)))

s = time.time()
arr2 = [i for i in range(int(1e+6))]
print('took {} secs'.format(round(time.time() - s, 3)))

这个范例做的事情很简单,首先我们引入了time模组。
并在两次创造List的前后计时,以算出执行所需时间。
由于每个人电脑的效能不同,算出来的时间会不一样。但基本上,使用List Comprehension的方式应该会比传统方法来的快很多。
以下是笔者在自己电脑上执行的结果:

took 0.148 secs
took 0.07 secs

引入模组

既然上面都用到了,那我们就顺便说说如何在Python引入模组吧!
引入模组的方法大概如下:

# standard import
import time

# import and give alias
import random as rd

# precise imoprt
from pathlib import Path

# useless statement
from datetime import *

要点:

  1. 使用import关键字引入模组
  2. 可引入模组后,用as帮他取昵称,这样就可以不用打又臭又长的套件名称XD
  3. 可使用import ... from ...的语法,从某套件中拿出特定的功能
  4. 最后一个方法感觉很糟,会污染全域,建议不要使用XD

List Comprehension背后的原理

让我们来稍微了解一下,List Comprehension这个神奇的东西好了。
先上范例:

# what if we don't assign comprehension to list?
comp = (i for i in range(10))
print(comp)
print(type(comp))

arr1 = list(comp)
arr2 = list(comp)
arr3 = [comp]
print(arr1)
print(arr2)
print(arr3)

先看前三行,我们用了List Comprehension,但没有把它放进List里面,而是把它塞在变数里,之后把他的值与型别印出来看看。
你会发现,其实他是一个叫做generator的东西,并且印出的时候,无法看到里面的值。
这个东西我们现在不谈,之后再细细说明。

接着我们下面的程式开始执行,猜猜看,arr1&arr2的值会不会一样?
执行后会发现,arr2是空List,原因是generator这个东西被arr1消耗掉了,所以arr2并没有拿到元素!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值