[CS61A]Lecture#14:List Mutation, Identity, and Nonlocal

仅用作个人学习记录
Reference:https://inst.eecs.berkeley.edu/~cs61a

List

List creation

从头建立列表:

a = []
b = [0, 1, 2, 3]

利用已有的列表创建列表:

c = b + [20, 30]
d = c[:]
e = list(c)
e2 = e

在这里插入图片描述

列表相加、切片和list()构造都返回一个新的列表,并不会改变参数列表。故都是非破坏性操作。

注意在列表的操作中+=并不是一个语法糖,即b = b + [20, 30]b += [20, 30]是不同的。+=是破坏性操作。

在这里插入图片描述

List mutation

对切片赋值是破坏性操作。

L = [1, 2, 3, 4, 5]
L[2] = 6
L[1:3] = [9, 8]
L[2:4] = []             # Deleting elements
L[1:1] = [2, 3, 4, 5]   # Inserting elements
L[len(L):] = [10, 11]   # Appending
L[0:0] = range(-3, 0)   # Prepending

List methods

list 是一个对象,对象有方法,方法就是在对象上调用函数。

append 和 extend

append()添加单个元素到列表中,单个元素、列表都可作为参数。

在这里插入图片描述

extend()添加一个列表中的所有元素到已有列表。相当于+=

在这里插入图片描述

extend()接受列表作为参数。

s = [2, 3]
s.extend(4) # TypeError: 'int' object is not iterable
s.extend([4])

appendextend都是破坏性操作。使用id可以发现,使用appendextend前后地址不变。

pop 和 remove

pop()移除列表最后一个元素,并将该元素返回。

在这里插入图片描述

pop也可接受参数,移除索引值为参数的值并返回该值。

remove()移除列表中第一个与参数相等的元素。

在这里插入图片描述

注意若列表中没有值与参数想匹配,则会引发异常。

s = [6, 7, 4, 8, 4]
try:
	s.remove(1)
except:
    print("ValueError: list.remove(x): x not in list")

显然,popremove都是破坏性操作。

Equality and Identity

Equality:exp0 ==exp1,==判断两个对象的值是否相等。

如果 exp0 和 exp1都包含相等数值的对象,则结果为True。

Identity :exp1 is exp1,is 判断两个对象是否完全相等。

如果 exp0 和 exp1为同一个对象,则结果为True。

>>> list1 = [1,2,3]
>>> list2 = [1,2,3]
>>> list1 == list2
True
>>> list1 is list2
False

相同的对象总是有相同的值。

>>> list1 = [1,2,3]
>>> list2 = list1
>>> list1 is list2
True
>>> list1 == list2
True

一般何时使用 is:

  • 判断一个值是否为空,a is none

  • 判断两个对象的类型是否一致,type(a) is type(b)

在处理数字和字符串时不要使用is,而是使用==。对于较小的数字和字符串时python会优化内存,这使我们会被is误导。

>>> a = 100
>>> b = 100
>>> a is b
True
>>> a = 1000000
>>> b = 1000000
>>> a is b
False

Scopes

Names inside local scopes

attendees = []
def mark_attendance(name):
	attendees.append(name)
	print("In attendance:", attendees)
mark_attendance("Emily")
mark_attendance("Cristiano")
mark_attendance("Samantha")
attendees = []
def mark_attendance(name):
	attendees = attendees + [name] # UnboundLocalError
	print("In attendance:", attendees)
mark_attendance("Emily")
mark_attendance("Cristiano")
mark_attendance("Samantha")

第二个程序不可行,在执行attendees = attendees + [name]时,并未在本地的环境帧中找到attendees,python 知道要在当前环境下创建一个新的名称attendees,并计算值与其绑定。而在计算attendees + [name]时,发现attendees并未赋值。出现错误referenced before assignment

解决办法1:

def mark_attendance(name):
 	global attendees
	attendees = attendees + [name] # UnboundLocalError
	print("In attendance:", attendees)

但使用global并不是一个好习惯,在函数内部重新分配全局变量会导致代码更加脆弱和不可预测。

解决办法2:

attendees = []
def mark_attendance(attendees, name):
	attendees = attendees + [name] # UnboundLocalError
	print("In attendance:", attendees)
    return attendees
mark_attendance(attendees, "Emily")
mark_attendance(attendees, "Cristiano")
mark_attendance(attendees, "Samantha")

Names inside nested scopes

def make_tracker(class_name):
	attendees = []
    
    def track_attendance(name):
        attendees.append(name)
        print(class_name, ": ", attendees)
        
    return track_attendance

tracker = make_tracker("CS61A")
tracker("Emily")
tracker("Cristiano")
tracker("Julian")
def make_counter(start):
    current = start
    
    def count():
        current = current + 1 # UnboundLocalError
        print("Count:", current)
        
    return count
counter = make_counter(30)
counter()
counter()
counter()

解决办法1:

def make_counter(start):
    current = start
    
    def count():
        nonlocal current
        current = current + 1  
        print("Count:", current)
        
    return count
counter = make_counter(30)
counter()
counter()
counter()

同样使用nonlocal并不是一个好习惯。nonlocal关键字仅添加到 Python 3,因此大多数可能使用它的代码都可以用更 Pythonic 的方式完成。

def make_counter(start):
    current = start
    
    while True:
        current = current + 1
        print("Count:", current)
        yield
    
counter = make_counter(30)
next(counter)
next(counter)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值