零基础学Python:列表推导式及深浅拷贝

列表推导式

Python里面有个很棒的语法糖(syntactic sugar),它就是 list comprehension ,有人把它翻译成“列表推导式”,也有人翻译成“列表解析式”。名字听上去很难理解,但是看它的语法就很清晰了。虽然名字叫做 list comprehension,但是这个语法同样适用于dict、set等这一系列可迭代(iterable)数据结构。

语法规范:


其中的 if 条件判断根据需要可有可无。
下面看一个具体的例子,生成一个包含10以内的偶数的list:


由for循环升级到列表推导式:
在没有了解 list comprehension 之前,上面那个生成偶数list的通常做法是用 for 循环:


很明显, for 循环占用了4行代码,而 list comprehension 只用了1行代码。
文章开始说到推导式的语法规范时,我们讲了 if 表达式是可有可无的,这也符合我们编程遇到的实际情况。比如,要生成一个10以内的整数的平方的列表:


复杂的嵌套循环
我们先来看一个例子,把一个矩阵(以列表为元素的列表)展平为一个列表。首先,我们用 for 循环来实现一下:


接着我们用列表推导式实现该功能:


还是一行代码就搞定,但一行里面有两个 for ,看起来很乱,两个 for ,哪个在前哪个在后呢?只要记住他们的顺序和不用推导式的原始for循环是一致的即可。
推导式的可读性
一行代码搞定几行代码的事情,看上去很简洁,但是读起来很费劲,尤其是当条件语句很长的时候,把这一行代码变得很长,超过了代码规范规定的长度(一般是80个字符),也使得理解代码变得困难。

 

面对一行长长的代码该如何下口读,如何理解呢?别着急,好在Python允许在中括号、花括号之间断行:
列表推导式的断行:
断行前:


断行后:


带嵌套循环的推导式的断行:
断行前:


断行后:


字典(dict)和集合(set)的推导式
前面我们也提到过,推导式不仅仅适用于列表,它同样使用于字典dict和集合set。
把一个字典的key和value互换:


用一个列表的所有单词的首字母生成一个集合:


通过以上讲解就可以轻松掌握Python的列表推导式( list comprehension )了,简而言之,就是把普通的多行for循环压缩成一行代码,这种压缩语法适用于列表、字典、集合等可迭代数据结构(iterables)。

 

深浅拷贝

对象引用、浅拷贝、深拷贝(拓展、难点、重点)
Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果

其实这个是由于共享内存导致的结果

拷贝:原则上就是把数据分离出来,复制其数据,并以后修改互不影响。
先看 一个非拷贝的例子

使用=赋值(对象引用)

=赋值:数据完全共享
=赋值是在内存中指向同一个对象,如果是可变(mutable)类型,比如列表,修改其中一个,另一个必定改变

如果是不可变类型 (immutable) ,比如字符串,修改了其中一个,另一个并不会变

 

浅拷贝(copy)

浅拷贝:数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层)

 

深拷贝(deepcopy)

深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)

深拷贝就是完完全全复制了一份,且数据不会互相影响,因为内存不共享。
深拷贝的方法有

 

总结:

copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。
copy.deepcopy 深拷贝 拷贝对象及其子对象

posted @ 2021-03-02 14:50  酸菜鱼学Python  阅读(150)  评论(0编辑  收藏  举报