code 1:
L = [lambda x : x*i for i in range(5)] print([n(2) for n in L])
正确结果:
[8, 8, 8, 8, 8]
原因是,L 中的每一个元素都是一个 lambda 函数,这些 lambda 函数都使用了外部变量 i,而 i 的值在循环结束后是 4,因此每个 lambda 函数中 i 的值都是 4。当执行 [n(2) for n in l] 时,每个 lambda 函数都会返回 2*4=8,因此最终结果是 [8, 8, 8, 8, 8]。
错误结果:
[0, 2, 4, 6, 8]explain:
代码涉及lambda 表达式、列表推导式、作用域和变量捕获。
lambda 表达式是一种匿名函数,可以用于创建简单的函数。在这段代码中,使用 lambda 表达式创建了一个带有一个参数 x 的函数,函数的返回值是 x 乘以 i。由于 i 是在 for 循环中定义的变量,因此在 lambda 表达式中可以访问它。这个 lambda 表达式创建了 5 个函数,分别对应 i 取值为 0 到 4。
列表推导式是一种快速创建列表的方法,可以根据某种规则快速生成列表。在这段代码中,使用列表推导式生成了包含 5 个 lambda 函数的列表。
作用域和变量捕获是 lambda 表达式的一个重要特性。在 lambda 表达式中,可以访问外部作用域中的变量,这被称为变量捕获。代码中,lambda 表达式访问了循环中定义的变量 i,而这个变量在循环结束后的值是 4,因此每个 lambda 函数中 i 的值都是 4。
避免:这个问题可以通过增加一个默认参数来避免,这个默认参数可以保存当前循环的值,从而避免了变量捕获的问题。
L = [lambda x, i=i : x*i for i in range(5)] print([n(2) for n in L]) # 输出 [0, 2, 4, 6, 8]
code2:
print(['1',2,'1',2,'1',2,][10:]) #[] LL = [[' ']]*5 print(LL)# [[' '], [' '], [' '], [' '], [' ']] LL0 = LL[0].append(10) print(LL) #[[' ', 10], [' ', 10], [' ', 10], [' ', 10], [' ', 10]] LL1 = LL[1].append(20) print(LL) #[[' ', 10, 20], [' ', 10, 20], [' ', 10, 20], [' ', 10, 20], [' ', 10, 20]] LL2 = LL.append(30) print(LL) #[[' ', 10, 20], [' ', 10, 20], [' ', 10, 20], [' ', 10, 20], [' ', 10, 20], 30] list1 = [1, 3, 5, 8, 10, 13, 18, 36, 78] print(list1[::-1]) #[78, 36, 18, 13, 10, 8, 5, 3, 1] print(list1[::2]) #[1, 5, 10, 18, 78] print(list1[::3]) #[1, 8, 18]
explain:
1>.['1',2,'1',2,'1',2,]只有6个元素,因此从第10个元素开始取就没有元素了,所以输出一个空列表
[]
。2>.创建了一个包含5个子列表的二维列表
LL
,每个子列表都包含一个空格字符。3>.将
LL[0]
子列表的末尾添加了一个整数10,因为LL
中的每个子列表实际上都是同一个对象的引用,所以修改一个子列表的内容,其他子列表也会受到影响,因此LL
中的所有子列表都末尾添加了整数10。4>.将
LL[1]
子列表的末尾添加了一个整数20,同样会影响到LL
中的所有子列表。5>.整数30添加到
LL
的末尾,此时LL
包含6个子列表,最后一个子列表就是整数30。6>.输出
list1
的倒序,即[78, 36, 18, 13, 10, 8, 5, 3, 1]
。7>.输出
list1
从第一个元素开始,每隔一个元素取一个,即[1, 5, 10, 18, 78]
。8>.输出
list1
从第一个元素开始,每隔两个元素取一个,即[1, 8, 18]
。note:append方法用作在原列表末尾添加元素,没有返回值(或返回值为None),所以LL0、LL1、LL2的值均为None