python:列表

本文详细介绍了Python中的列表,包括列表的创建、元素的添加、修改和删除,以及列表的遍历、切片、索引、排序等操作。此外,还讲解了列表生成式、生成器表达式等高级用法,以及列表在内存中的表示和可变性。列表是Python中最常用的数据结构之一,支持多种操作,如append、insert、extend、sort等,可用于存储和处理各种数据。
摘要由CSDN通过智能技术生成

列表

  • 列表是Python中的一个对象
  • 对象(object)就是内存中专门用来存储数据的一块区域
  • 之前我们学习的对象,像数值,它只能保存一个单一的数据,列表中可以保存多个数据
  • 列表是用来存储对象的对象

List(列表) 是 Python 中使用最频繁的数据类型。

  • 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。
  • 列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
    • 一个列表在另一个列表中,称为嵌套列表。
    • 一个不包含元素的列表被称为空列表;你可以用空的方括号 [] 创建一个空列表。
  • list是一个可变序列
    • 列表中的对象都会按照插入的顺序存储到列表中,
      • 第一个插入的对象保存到第一个位置,第二个保存到第二个位置
    • 我们可以通过索引(index)来获取列表中的元素
      • 索引是元素在列表中的位置,列表中的每一个元素都有一个索引
      • 索引是从0开始的整数,列表第一个位置索引为0,第二个位置索引为1,第三个位置索引为2,以此类推
# 创建列表,通过[]来创建列表
my_list = [] # 创建了一个空列表
# print(my_list , type(my_list))



# 列表存储的数据,我们称为元素
# 一个列表中可以存储多个元素,也可以在创建列表时,来指定列表中的元素
my_list = [10] # 创建一个只包含一个元素的列表

# 当向列表中添加多个元素时,多个元素之间使用,隔开
my_list = [10,20,30,40,50] # 创建了一个保护有5个元素的列表


# 乘号表示列表元素的重复
list2 = ['hello'] * 3
print(list2) # ['hello', 'hello', 'hello']

# 列表中可以保存任意的对象
my_list = [10,'hello',True,None,[1,2,3],print]

类型转换

可以将可迭代的内容转换成列表:

# 字符串
y = '1345'
list(y) # ['1', '3', '4', '5'] 将列表转换成列表

# 元组
z = ('a', 'b', 'c')
list(z) # ['a', 'b', 'c'] 将元组转换成列表

# 字典
d = {'Name': 'Tom', 'Age': 7, 'Class': 'First'}
list(d) # ['Name', 'Age', 'Class'] 字典 key 转成列表
list(d.values()) # ['Tom', 7, 'First'] 字典 value 转成列表
# 字典键值对(一个元组)转成列表
list(d.items()) # [('Name', 'Tom'), ('Age', 7), ('Class', 'First')]

访问列表中的值

与字符串的索引一样,列表索引从 0 开始,第二个索引是 1,依此类推。如果使用的索引超过了最大的范围,会抛出异常: list index out of range

列表下标的工作原理和字符串下标相同:

  • 任何整数表达式都可以用作下标。
  • 如果你试图读或写一个不存在的元素,你将会得到一个索引错误
  • 如果下标是负数,它将从列表的末端开始访问列表

通过索引列表可以进行截取、组合等操作。
在这里插入图片描述

#!/usr/bin/python3

list = ['red', 'green', 'blue', 'yellow', 'white', 'black']
print( list[0] )
print( list[1] )
print( list[2] )

以上实例输出结果:

red
green
blue

索引也可以从尾部开始,最后一个元素的索引为 -1,往前一位为 -2,以此类推。
在这里插入图片描述

#!/usr/bin/python3

list = ['red', 'green', 'blue', 'yellow', 'white', 'black']
print( list[-1] )
print( list[-2] )
print( list[-3] )

以上实例输出结果:

black
white
yellow

列表中的列表或者元组的索引读取

x = ['a', 1.5, True, [2, 3, 4]] # 各种类型混杂
x[-1][2] # 2 先取到内部的列表元素,再按正常的列表进行切片

切片

切片指从现有列表中,获取一个子列表

  • 通过切片来获取指定的元素
    • 语法:列表[起始:结束]
      • 通过切片获取元素时,会包括起始位置的元素,不会包括结束位置的元素
      • 做切片操作时,总会返回一个新的列表,不会影响原来的列表
      • 起始和结束位置的索引都可以省略不写
        • 如果省略结束位置,则会一直截取到最后
        • 如果省略起始位置,则会从第一个元素开始截取
        • 如果起始位置和结束位置全部省略,则相当于创建了一个列表的副本
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精']

 print(stus[1:])
 print(stus[:3])
 print(stus[:])
 print(stus)
  • 语法:列表[起始:结束:步长]
    • 步长表示,每次获取元素的间隔,默认值是1
      print(stus[0:5:3])
    • 步长不能是0,但是可以是负数
      print(stus[::0]) ValueError: slice step cannot be zero
    • 如果是负数,则会从列表的后部向前边取元素
      print(stus[::-1])

对序列使用+和*

列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。

  • +可以将两个列表拼接为一个列表
    • 通常 + 号两侧的序列由相同类型的数据所构成
    • 在拼接的过程中,两个被操作的序列都不会被修改,Python 会新建一个包含同样类型数据的序列来作为拼接的结果。
my_list = [1,2,3] + [4,5,6]
  • * 可以将列表重复指定的次数
    • 如果在 a * n 这个语句中,序列 a 里的元素是对其他可变对象的引用的话,你就需要格外注意了,因为这个式子的结果可能会出乎意料。比如,你想用my_list = [[]] * 3 来初始化一个由列表组成的列表,但是你得到的列表里包含的 3 个元素其实是 3 个引用,而且这 3 个引用指向的都是同一个列表。这可能不是你想要的效果。
my_list = [1,2,3] * 5   # [1, 2, 3,     1, 2, 3,    1, 2, 3,    1, 2, 3,    1, 2, 3]

在这里插入图片描述
在这里插入图片描述

列表是可变的

列表用外部标有 “list” 的盒子表示,盒子内部是列表的元素。cheeses 指向一个有 3 个元素的列表,3 个元素的下标分别是 0、1、2。numbers 包含两个元素;状态图显示第二个元素原来是 123,被重新赋值为 5。empty 对应一个没有元素的列表。
在这里插入图片描述

和字符串不同的是,列表是可变的

>>> a = [1, 2, 3, 4, 5, 6]
>>> a[0] = 9
>>> a[2:5] = [13, 14, 15]
>>> a[2:5] = []   # 将对应的元素值设置为 []

列表遍历

最常用的遍历列表的方式是使用 for 循环。语法和字符串遍历类似

  • 如果你只需要读取列表中的元素
# 通过for循环遍历列表元素
for elem in list1:
    print(elem)
  • 然而,如果你想要写入或者更新列表中的元素,你需要通过下标访问。一种常用的方法是结合内置函数 range 和 len :
    • 这个循环将遍历列表并更新每个元素。
    • len 返回列表中的元素个数。
    • range 返回一个包含从 0 到 n − 1 下标的列表,其中 n 是列表的长度。
    • 每次循环中,i 得到下一个元素的下标。循环主体中的赋值语句使用 i 读取该元素的旧值,并赋予其一个新值。
for i in range (len ( numbers ) ) :
numbers [ i ] = numbers [ i ] * 2
  • 对一个空列表执行 for 循环时,将不会执行循环的主体:
for x in []:
  print ('This ␣ never ␣ happens .')


# 通过enumerate函数处理列表之后再遍历可以同时获得元素索引和值
for index, elem in enumerate(list1):
    print(index, elem)

映射、筛选和归并

把一个列表中的元素加起来是一个很常用的操作,所以 Python 将其设置为一个内建内置函数 sum :

>>> t = [1 , 2 , 3]
>>> sum ( t )
6

一个像这样的将一系列的元素合并成一个单一值的操作有时称为归并 (reduce) 。

有时,你在构建一个列表时还需要遍历另一个列表。例如,下面的函数接受一个字符串列表

def capitalize_all ( t ) :
res = []
for s in t:
	res.append(s.capitalize())
return res

res 被初始化为一个空列表;每次循环时,我们添加下一个元素。所以 res 是另一种形式的累加器。

类似 capitalize_all 这样的操作有时被称为映射 (map) ,因为它 ‘‘映射’’ 一个函数到序列中的每个元素上。

另一个常见的操作是从列表中选择一些元素,并返回一个子列表。例如,下面的函数读取一个字符串列表,并返回一个仅包含大写字符串的列表:

def only_upper ( t ) :
res = []
for s in t:
	if s.isupper () :
	res.append ( s )
return res

isupper 是一个字符串方法,如果字符串仅含有大写字母,则返回 True。

类似 only_upper 这样的操作被称为筛选 (filter) ,因为它选中某些元素,然后剔除剩余的元素。

大部分常用列表操作可以用映射、筛选和归并这个组合表示。

列表和字符串

一个字符串是多个字符组成的序列,一个列表是多个值组成的序列。但是一个由字符组成的列表不同于字符串。可以使用 list 将一个字符串转换为字符的列表:

>>> s = 'spam '
>>> t = list ( s )
>>> t
['s', 'p', 'a', 'm']

list 函数将字符串分割成单独的字符。如果你想将一个字符串分割成一些单词,你可以使用 split 方法:

>>> s = 'pining ␣for ␣the ␣ fjords '
>>> t = s . split ()
>>> t
['pining ', 'for ', 'the ', 'fjords ']

可以提高一个叫做分隔符 (delimiter) 的可选参数,指定什么字符作为单词之间的分界线。下面的例子使用连字符作为分隔符:

>>> s = 'spam−spam−spam '
>>> delimiter = '−'
>>> t = s.split( delimiter )
>>> t
['spam ', 'spam ', 'spam ']

join 的功能和 split 相反。它将一个字符串列表的元素拼接起来。join 是一个字符串方法,所以你需要在一个分隔符上调用它,并传入一个列表作为参数:

>>> t = ['pining ', 'for ', 'the ', 'fjords ']
>>> delimiter = '␣'
>>> s = delimiter.join ( t )
>>> s
'pining ␣for ␣the ␣ fjords '

对象和值

如果我们执行下面的赋值语句:

a = 'banana '
b = 'banana '

我们知道 a 和 b 都指向一个字符串,但是我们不知道是否他们指向同一个 字符串。这里有两种可能的状态

在这里插入图片描述
一种情况是,a 和 b 指向两个有相同值的不同对象。第二种情况是,它们指向同一个对象。

为了查看两个变量是否指向同一个对象,你可以使用 is 运算符。

>>> a = 'banana '
>>> b = 'banana '
>>> a is b
True  # 相同



>>> a = [1 , 2 , 3]
>>> b = [1 , 2 , 3]
>>> a is b  #相等
False

别名

如果 a 指向一个对象,然后你赋值 b = a ,那么两个变量指向同一个对象:

在这里插入图片描述

>>> a = [1 , 2 , 3]
>>> b = a
>>> b is a
True

变量和对象之间的关联称为引用 (reference) 。在这个例子中,有两个对同一个对象的引用。
如果一个对象有多于一个引用,那它也会有多个名称,我们称这个对象是有别名5 。

如果一个有别名的对象是可变的,对其中一个别名的改变对影响到其它的别名:

>>> b [0] = 42
>>> a
[42 , 2 , 3]

尽管这个行为很有用,但是容易导致出现错误。通常,避免对于可变对象使用别名相对更安全。

对于像字符串这样的不可变对象,使用别名没有什么问题。例如:

a = 'banana '
b = 'banana '

a 和 b 是否指向同一个字符串基本上没有什么影响

当你将一个列表作为参数传给一个函数,函数将得到这个列表的一个引用。如果函数对这个列表进行了修改,会在调用者中有所体现。

列表的CURD

大部分的列表方法都是无返回值的;它们对列表进行修改,然后返回 None。

添加元素

添加元素有一下几个方法:

append 在末尾添加元素

append会把新元素添加到列表末尾

#定义变量A,默认有3个元素 
A = ['xiaoWang','xiaoZhang','xiaoHua']

A.append("annny”) 
print("‐‐‐‐‐添加之后,列表A的数据‐‐‐‐‐A=%s" % A)

insert 在指定位置插入元素

  • 向列表的指定位置插入一个元素
  • 参数:
    • 1.要插入的位置
    • 2.要插入的元素
strs = ['a','b','m','s'] 
strs.insert(3,'h') 
print(strs) # ['a', 'b', 'm', 'h', 's']

extend 合并两个列表

通过extend可以将另一个列表中的元素逐一添加到列表中

a = ['a','b','c'] 
b = ['d','e','f'] 
a.extend(b) 
print(a) # ['a', 'b', 'c', 'd', 'e', 'f'] 将 b 添加到 a 里 
print(b) # ['d','e','f'] b的内容不变



stus = ['孙悟空','猪八戒','沙和尚','唐僧']
stus.extend(['唐僧','白骨精'])
# 相当于
stus += ['唐僧','白骨精']

修改元素

通过索引

修改元素的时候,为指定的列表下标赋值即可。

#定义变量A,默认有3个元素 
A = ['xiaoWang','xiaoZhang','xiaoHua'] 
print("‐‐‐‐‐修改之前,列表A的数据‐‐‐‐‐A=%s" % A) 

#修改元素 
A[1] = 'xiaoLu' 
print("‐‐‐‐‐修改之后,列表A的数据‐‐‐‐‐A=%s" % A)

通过切片来修改列表

# 在给切片进行赋值时,只能使用序列
stus[0:2] = ['牛魔王','红孩儿'] 使用新的元素替换旧元素
stus[0:2] = ['牛魔王','红孩儿','二郎神']
stus[0:0] = ['牛魔王'] # 向索引为0的位置插入元素
# 当设置了步长时,序列中元素的个数必须和切片中元素的个数一致
stus[::2] = ['牛魔王','红孩儿','二郎神']

不可变序列的中间

s = 'hello'
# s[1] = 'a' 不可变序列,无法通过索引来修改
# 可以通过 list() 函数将其他的序列转换为list
s = list(s)
print(s)

查找元素

in,not in

看看指定的元素是否存在

  • in(存在),如果存在那么结果为true,否则为false
  • not in(不存在),如果不存在那么结果为true,否则false
#待查找的列表 
nameList = ['xiaoWang','xiaoZhang','xiaoHua'] 

#获取用户要查找的名字 
findName = input('请输入要查找的姓名:') 

#查找是否存在 
if findName in nameList: 
	print('在列表中找到了相同的名字') 
else:
	print('没有找到')

index()

  • 功能: 获取指定元素在列表中的第一次出现时索引
  • 参数:
    • 第二个参数,表示查找的起始位置
    • 第三个参数,表示查找的结束位置
  • 注意 : 如果要获取列表中没有的元素,会抛出异常
print(stus.index('沙和尚'))
print(stus.index('沙和尚',3,7))

print(stus.index('牛魔王')) ValueError: '牛魔王' is not in list

删除元素

pop

  • 根据索引删除并返回被删除的元素:
    • pop 修改列表,并返回被移除的元素。
    • 如果你不提供下标,它将移除并返回最后一个元素。
result = stus.pop(2) # 删除索引为2的元素
result = stus.pop() # 删除最后一个

del

  • 如果你不需要被移除的元素,可以使用 del 运算符:
#!/usr/bin/python3
 
list = ['Google', 'Runoob', 1997, 2000]
 
print ("原始列表 : ", list)
del list[2]            # 删除索引为2的元素
print ("删除第三个元素 : ", list)


# 通过切片来删除元素
del stus[0:2]
del stus[::2]
stus[1:3] = []

  • 要移除多个元素,你可以结合切片索引使用 del :
>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> del t [1:5]
>>> t
['a', 'f']

remove

  • 删除指定值得元素,如果相同值得元素有多个,只会删除第一个
>>> t = ['a', 'b', 'c']
>>> t.remove ('b')
>>> t
['a', 'c']

clear

# 清空序列
stus.clear()

其他

排序:sort

  • 用来对列表中的元素进行排序,默认是升序排列
  • 如果需要降序排列,则需要传递一个reverse=True作为参数
my_list. sort ()
my_list.sort(reverse=True)
sorted(a) # 返回一个排序的列表,但不改变原列表

min,max

# min() 获取列表中的最小值
# max() 获取列表中的最大值
arr = [10,1,2,5,100,77]
# print(min(arr) , max(arr))

count

# s.count() 统计指定元素在列表中出现的次数
print(stus.count('牛魔王'))

reverse

# 用来反转列表
stus.reverse()

列表解析

遍历并修改列表

  • 过时的解析:
    在这里插入图片描述
  • []表示要构建一些新的列表

在这里插入图片描述

  • 上面相当于下面:

在这里插入图片描述

表达式

列表推导是构建列表(list)的快捷方式,而生成器表达式则可以用来创建其他任何类型的序列。

列表推导表达式

推导式就是用 for 循环结合 if 表达式生成一个列表,这是一个非常方便紧凑地定义一个列表的方式,可以大大减少代码量。

# 将一个可迭代的对象展开形成一个列表
 list(range(1, 11))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[i for i in range(5)]
# [0, 1, 2, 3, 4]
[x * x for x in range(1, 11)]
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]



# 可以将结果进行处理
['第'+str(i) for i in range(5)]
# ['第0', '第1', '第2', '第3', '第4']

# 可以进行条件筛选, 实现取偶数
 [x * x for x in range(1, 11) if x % 2 == 0]
#[4, 16, 36, 64, 100]


#  列表生成式也可以使用两个变量来生成list:
L = ['Hello', 'World', 'IBM', 'Apple']
 [s.lower() for s in L]
#['hello', 'world', 'ibm', 'apple']

# 拆开字符, 过滤空格,全变成大写
[i.upper() for i in 'Hello world' if i != ' ']
# ['H', 'E', 'L', 'L', 'O', 'W', 'O', 'R', 'L', 'D']
# 对于复杂逻辑可以分行编写
[i.upper()
 for i in 'Hello world'
 if i != ' '
]

# 条件分支
data= ['good','bad','bad','good','bad']
[1 if x == 'good' else 0 for x in data]
# [1, 0, 0, 1, 0]


#  还可以使用两层循环,可以生成全排列( 三层和三层以上的循环就很少用到了):
 [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

使用原则:只用列表推导来创建新的列表,并且尽量保持简短。如果列表推导的代码超过了两行,你可能就要考虑是不是得用 for 循环重写了。

if … else

例如,以下代码正常输出偶数:

>>> [x for x in range(1, 11) if x % 2 == 0]
[2, 4, 6, 8, 10]

但是,我们不能在最后的if加上else:

>>> [x for x in range(1, 11) if x % 2 == 0 else 0]
  File "<stdin>", line 1
    [x for x in range(1, 11) if x % 2 == 0 else 0]
                                              ^
SyntaxError: invalid syntax

这是因为跟在for后面的if是一个筛选条件,不能带else,否则如何筛选?

如果把if写在for前面必须加else,否则报错:

>>> [x if x % 2 == 0 for x in range(1, 11)]
  File "<stdin>", line 1
    [x if x % 2 == 0 for x in range(1, 11)]
                       ^
SyntaxError: invalid syntax

这是因为for前面的部分是一个表达式,它必须根据x计算出一个结果。因此,考察表达式:x if x % 2 == 0,它无法根据x计算出结果,因为缺少else,必须加上else:

>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

上述for前面的表达式x if x % 2 == 0 else -x才能根据x计算出确定的结果。

可见,在一个列表生成式中,for前面的if … else是表达式,而for后面的if是过滤条件,不能带else。

生成器表达式

虽然也可以用列表推导来初始化元组、数组或其他序列类型,但是生成器表达式是更好的
选择。这是因为生成器表达式背后遵守了迭代器协议,可以逐个地产出元素,而不是先建
立一个完整的列表,然后再把这个列表传递到某个构造函数里。

生成器表达式的语法跟列表推导差不多,只不过把方括号换成圆括号而已:

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?

如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:

>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

当然,上面这种不断调用next(g)实在是太变态了,正确的方法是使用for循环,因为generator也是可迭代对象:

>>> g = (x * x for x in range(10))
>>> for n in g:
...     print(n)
... 
0
1
4
9
16
25
36
49
64
81

所以,我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

比如斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1
    return 'done'

仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。

也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator函数,只需要把print(b)改为yield b就可以了:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator:

>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>

这里,最难理解的就是generator函数和普通函数的执行流程不一样。普通函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

举个简单的例子,定义一个generator函数,依次返回数字1,3,5:

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)

调用该generator函数时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:

>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

可以看到,odd不是普通函数,而是generator函数,在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next(o)就报错。

请务必注意:调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。比如下面:

>>> next(odd())
step 1
1
>>> next(odd())
step 1
1
>>> next(odd())
step 1
1

odd()会创建一个新的generator对象,上述代码实际上创建了3个完全独立的generator,对3个generator分别调用next()当然每个都会返回第一个值。

回到fib的例子,我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

同样的,把函数改成generator函数后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代:

for n in fib(6):
    print(n)

但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

要理解generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。

请注意区分普通函数和generator函数,普通函数调用直接返回结果:

>>> r = abs(6)
>>> r
6

generator函数的调用实际返回一个generator对象:

>>> g = fib(6)
>>> g
<generator object fib at 0x1022ef948>

笔试

请按alist中元素的age由大到小排序

alist = [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}]

def sort_by_age(list1):
	return sorted(alist,key=lambda x:x['age'],reverse=True)


alist_sort = sorted(alist,key=lambda e: e.__getitem__('age'),reverse=True)

下面输出什么

list = ['a','b','c','d','e']
print(list[10:])

代码将输出[],不会产生IndexError错误,就像所期望的那样,尝试用超出成员的个数的index来获取某
个列表的成员。例如,尝试获取list[10]和之后的成员,会导致IndexError。然而,尝试获取列表的切
片,开始的index超过了成员个数不会产生IndexError,而是仅仅返回一个空列表。这成为特别让人恶
心的疑难杂症,因为运行的时候没有错误产生,导致Bug很难被追踪到。

写一个列表生成式,产生一个公差为11的等差数列

print([x*11 for x in range(10)])

给定两个列表,怎么找出他们相同的元素和不同的元素?

list1 = [1,2,3]
list2 = [3,4,5]
set1 = set(list1)
set2 = set(list2)
print(set1 & set2)
print(set1 ^ set2)
A,B 中相同元素: print(set(A)&set(B))
A,B 中不同元素: print(set(A)^set(B))

请写出一段python代码实现删除list里面的重复元素?

l1 = ['b','c','d','c','a','a']
l2 = list(set(l1))
print(l2)
def distFunc3(a):
	"""使用字典"""
	b = {}
	b = b.fromkeys(a)
	c = list(b.keys())
	print(c)

用list类的sort方法:

l1 = ['b','c','d','c','a','a']
l2 = list(set(l1))
l2.sort(key=l1.index)
print(l2)

也可以这样写:

l1 = ['b','c','d','c','a','a']
l2 = sorted(set(l1),key=l1.index)
print(l2)

也可以用遍历:

l1 = ['b','c','d','c','a','a']
l2 = []

def distFunc2(a):
"""将一个列表的数据取出放到另一个列表中,中间作判断"""
	list = []
	for i in a:
		if i not in list:
			list.append(i)
	#如果需要排序的话用sort
	list.sort()
	print(list)

遍历列表时删除元素的正确做法

遍历在新在列表操作,删除时在原来的列表操作

a = [1,2,3,4,5,6,7,8]
print(id(a))
print(id(a[:]))

for i in a[:]:
	if i>5:
		pass
	else:
		a.remove(i)

print(a)
print('-----------')
print(id(a))
#filter
a=[1,2,3,4,5,6,7,8]
b = filter(lambda x: x>5,a)
print(list(b))

列表解析

a=[1,2,3,4,5,6,7,8]
b = [i for i in a if i>5]
print(b)

倒序删除
因为列表总是‘向前移’,所以可以倒序遍历,即使后面的元素被修改了,还没有被遍历的元素和其坐标还是保持不变的

a=[1,2,3,4,5,6,7,8]
print(id(a))

for i in range(len(a)-1,-1,-1):
	if a[i]>5:
		pass
	else:
		a.remove(a[i])

print(id(a))
print('-----------')
print(a)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值