引言

‍♂️作者简介:生鱼同学,大数据科学与技能专业硕士在读‍,曾获得华为杯数学建模国家二等奖,MathorCup 数学建模比赛国家二等奖,亚太数学建模国家二等奖。

✍️研讨方向:杂乱网络科学

爱好方向:运用python进行数据分析与机器学习,数学建模比赛经验沟通,网络爬虫等。

在python学习的过程中,咱们最早接触到的就是python的数组,元组,字典等根底类型,但很少有人深化谈论python的内置序列类型以及它们的高档运用姿态。

深度学习python的内置序列,不仅能让咱们编写的API愈加的易用简介,也能够更好的了解python中各种序列的特性。

在本文中,咱们就来一同解锁python内置序列的高档用法,玩转pyhon序列。

内置序列类型

python中有许多的序列类型,主要能够分为以下两类:

  • 容器序列:能寄存不同数据类型的数据的序列。(list, tuple, collections.deque)
  • 扁平序列:只能包容一种类型的序列。(str, bytes, bytearray, memoryview, array.array)

阐明:扁平序列储存的是一段接连的内存空间,而容器序列寄存的是它们包含的恣意类型目标的引用。

别的,序列类型还能够从可修改与不可修改的视点进行分类,主要能被分成以下两类:

  • 可变序列:list, bytearray, array.array, collections.deque, memoryview
  • 不可变序列:str, tuple, bytes

为了深化的谈论可变序列与不可变序列的差异,咱们看下面这个UML图:

【python进阶】你还在使用for循环新建数组?生成器表达式帮你一行解决
在上图中,承继从子类指向超类,能够看到可变序列(MutableSequence)承继了不可变序列(Sequence)的许多办法。与此一起,经过UML图咱们也能够更直观的发现其不同的地方,这有助于咱们了解后续的内置序列类型的差异。

列表推导与生成器表达式

列表推导

信任咱们已经对根底的序列类型list有了初步的了解与知道,但当咱们想要创立一个新的数组时,往往会想到运用for循环遍历生成。

其实在python中还存在一种构建列表的办法叫做列表推导(list comprehension),它是构建列表的快捷方式,一起也能够使你的代码愈加易读与简练。假定咱们需求创立从0到10的一个列表,咱们来看下面的两段代码:

# 不运用列表推导
example_list_01 = []
for i in range(10):
   example_list_01.append(i)
print(example_list_01)
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 列表推导
example_list_01 = [i for i in range(10)]
print(example_list_01)
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

信任大部分人第一时间都会考虑运用第一种办法进行列表的创立,但明显运用了列表推导(生成器表达式推导列表)的比如看起来愈加简便且易读。咱们再来看一个更杂乱的比如,假定咱们想要寻觅10以内的偶数,咱们看下面两段代码:

# 不运用列表推导
example_list_02 = []
for i in range(10):
    if i % 2 == 0:
       example_list_02.append(i)
print(example_list_02)
# 列表推导
example_list_02 = [i for i in range(10) if i % 2 == 0]
print(example_list_02)

明显,下面的代码可读性更强且更为简单。别的,运用filter也能够完结上述的功用,但是可读性并不强。咱们运用filter完结上述功用的代码如下:

example_list_03 = list(filter(lambda i: i % 2 == 0, range(10)))
print(example_list_03)

明显,这样的可读性并不强。

在列表推导中,咱们还能够将自己的函数或者python内置函数直接对生成的数组进行处理,请看下面这个比如:

def deal(num):
    return '处理过的' + str(num)
deal_list = [deal(i) for i in range(10)]
print(deal_list )
>>> ['处理过的0',
 '处理过的1',
 '处理过的2',
 '处理过的3',
 '处理过的4',
 '处理过的5',
 '处理过的6',
 '处理过的7',
 '处理过的8',
 '处理过的9']

最终,咱们再用列表推导表达式测验核算笛卡尔积并与for循环完结的相同的功用做比照,请看下面的代码:

colors = ['赤色','蓝色','绿色']
clothes = ['上衣','裤子','运动鞋']
clothes_list_01 = []
for color in colors:
    for clothe in clothes:
        clothes_list_01.append((color,clothe))
print('未运用列表推导:',clothes_list_01)
clothes_list_02 = [(color,clothe) for color in colors for clothe in clothes]
print('运用列表推导:',clothes_list_01)

结果如下:

未运用列表推导: [('赤色', '上衣'), ('赤色', '裤子'), ('赤色', '运动鞋'),
('蓝色', '上衣'), ('蓝色', '裤子'), ('蓝色', '运动鞋'), ('绿色', '上衣'), ('绿色', '裤子'), ('绿色', '运动鞋')]
运用列表推导: [('赤色', '上衣'), ('赤色', '裤子'), ('赤色', '运动鞋'), 
('蓝色', '上衣'), ('蓝色', '裤子'), ('蓝色', '运动鞋'), ('绿色', '上衣'), ('绿色', '裤子'), ('绿色', '运动鞋')]

能够看到输出的结果是完全相同的,但是运用列表推导的代码更为简练。

生成器表达式

尽管运用上述的列表推导语法也能够生成元组等其他类型的序列,但是运用生成器表达式会更好。生成器并不是先树立一个完整的列表再将其传递到某个构造函数内,而是逐一产出元素,这会愈加的节约内存。

咱们看下面几个比如,用来了解生成器表达式是如何生成字典与元组的。

# 运用生成器表达式构建字典
dict_transform_list = [('APPLE', '苹果'), ('BNANA', '香蕉'), ('PEAR', '梨子')]
dict_01 = {key: value for key,value in dict_transform_list}
>>>{'APPLE': '苹果', 'BNANA': '香蕉', 'PEAR': '梨子'}
# 运用生成器表达式构建元组
tuple_01 = tuple(i for i in range(10))
>>>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

总结

在本文中,介绍了生成器与表达式的用法,协助咱们快速创立数组以及其他序列,解锁了python序列的新姿态。

在后续的更新中,我将持续对元组的高档姿态和玩法进行介绍。

假如你觉得本文对你有协助的话,期望你点个收藏或帮我点个赞,假如有其他问题也能够私信我与我沟通或在谈论区与我谈论,咱们下次再会。