Python基础知识——3、操作列表

3、操作列表

  • for循环
    Python根据缩进来判断代码行与前一个代码行的关系。在for循环中,利用缩进表示代码块。for语句末尾的冒号告诉Python,下一行是循环的第一行。
bicycles = ['trek','cannondale','redline','specialized']

for bicycle in bicycles:
    print(bicycle)

输出:
trek
cannondale
redline
specialized

在for循环后,没有缩进的代码都只执行一次,不会重复执行。

  • range()函数
    生成一系列数,左闭右开,可用于for循环或者产生可迭代结构,如列表,调用有以下两种:
    range(stop:int), 从0产生一些列整数,到stop的前一个值处停止。
    range(start:int, stop:int, step:int), 从start开始,以step为步长,到stop的前一个数停止。如果步长太长,最后一个输出的数也绝不会超过stop的前一个数,如下面代码示例。
numbers = list(range(3))  # range(stop:int)
print(numbers)

enven_numbers = list(range(2,11,2)) #range(start:int, stop:int, step:int)
all_numbers = list(range(1,11,5))
print(enven_numbers)
print(all_numbers)

输出:
[0, 1, 2]
[2, 4, 6, 8, 10]
[1, 6]
  • for循环的两种重要用法
    • 利用enumerate()同时访问列表下标和值
    • 利用range()函数遍历列表的下标
'''
Author: your name
Date: 2021-10-09 09:40:34
LastEditTime: 2021-10-24 20:20:11
LastEditors: Please set LastEditors
Description: In User Settings Eitem
FilePath: /Python/test/test.py
'''
items = [1,3,5]
#同时访问下标和值
for i, v in enumerate(items):
   print(i,v)

#访问下标
n = len(items)
for i in range(n):  
   for j in range(i+1, n):     #访问下标i+1到n-1的元素
       print(items[j])
      
输出:
0 1
1 3
2 5
3
5
5
  • 对数字列表执行简单的统计计算
  • min(iterable) : 取最小值
  • max (iterable) :取最大值
  • sum (iterable) : 取总和
digits = [1,2,3,4,5,6,7,8,9,0]

mi = min(digits)
ma = max(digits)
su = sum(digits)

print(f"mi = {mi}, ma = {ma}, su = {su}")

输出:
mi = 0, ma = 9, su = 45
  • 列表解析
    有时候我们需要创建复杂列表,如下面例子中的平方数列表,利用for循环有时显得不够简洁,列表解析将for循环和创建新元素的代码合并成一行,并自动附加新元素。
#例一
squares = [value**2 for value in range(1,11)]  
print(squares)

#例二
fruits = ['apple', 'banana', 'watermelon']
upper_fruits = [fruit.title() for fruit in fruits]  #后半部分和for语句的开头完全相同
print(upper_fruits)

输出:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
['Apple', 'Banana', 'Watermelon']
  • 使用列表的一部分——切片
    要创建切片,可指定要使用的第一个元素和最后一个元素的索引。两个索引之间用冒号隔开。与函数range()一样,Python在到达第二个索引之前的元素后停止。由于是左闭右开,用第二个索引值减去第一个索引值,得到的结果就是这个切片包含的元素数量。
item = list(range(0,10,1))
print(item)

cut_item = item[1:6]  #取索引为1处(即第二个元素)到索引为5处(左闭右开)元素
print(cut_item)

输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5]

如果没有指定第一个索引,Python将自动从列表开头开始。如果没有指定第二个索引,切片将终止于列表末尾。在给末尾元素切片时,可使用负数索引。
可以在两个索引之后添加第三个参数作为步长,它可以告诉Python在指定范围内每隔多少个元素提取一个。

item = list(range(0,10,1))
print(item)

head_cut = item[:3]  #不设置第一个索引
print(head_cut,"-------------------item[:3]")

tail_cut = item[4:]  #不设置第二个索引
print(tail_cut,"--------------------item[4:]")

tail_cut2 = item[-3:]  #使用负数索引
print(tail_cut2,"--------------------item[-3:]")

step_cut = item[1:8:2]  #设置切片步长
no_step_cut = item[1:8] #不设置切片步长
print(no_step_cut,"-------------------item[1:8]")
print(step_cut,"---------------------item[1:8:2]")

输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2] -------------------item[:3]
[4, 5, 6, 7, 8, 9] --------------------item[4:]
[7, 8, 9] --------------------item[-3:]
[1, 2, 3, 4, 5, 6, 7] -------------------item[1:8]
[1, 3, 5, 7] ---------------------item[1:8:2]

遍历切片——如果要遍历切片中的部分元素,可以在for循环中使用切片。

item = list(range(0,10,1))
print(item)

for i in item[:4]:  #计算前四个数的平方根
    print(i**2)
    
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0
1
4
9
  • 列表的多层切片
    列表的切片是可以嵌套的,理论情况下,只要上一层的切片不为空,就可以一直嵌套。这多层切片有一种很实用的应用是反转数组。对一个列表nums[::-1]也就是将步长设为-1,可以实现对列表某一部分的反转。如下例,利用多层切片实现对列表前四个数的反转:
nums = [1,2,3,4,5,6,7]
nums[0:4] = nums[0:4][::-1]
print(result)

输出:
[4, 3, 2, 1, 5, 6, 7]
  • 复制列表
    如果要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引( [:] )。这样Python就创建了一个起始于第一个元素、终止于最后一个元素的切片,即整个列表的副本。
    值得一提的是,如果我们将一个列表直接赋值给另一个列表,两个列表会指向同一个内存空间,当改变其中一个的值时,另一个列表的值也会被改变。如果像前面所述利用切片创建复制,得到的新列表会指向另外的空间,对任何一个列表的操作不会出现在另一个列表中。
item = list(range(0,10,1))
print(item)

print("切片复制测试:")
copy_item = item[:]
print(copy_item)

copy_item.append(666)   #只有copy_item会在末尾插入666
print(item)
print(copy_item)

print("直接赋值测试:")
assignment_item = item
print(assignment_item)

assignment_item.append(666)  #两个列表会同时在末尾插入666
print(item)
print(assignment_item)

输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
切片复制测试:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 666]
直接赋值测试:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 666]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 666]
  • 一个有趣的讨论:切片是不是列表一部分的复制
    切片是不是列表一部分的复制,这一问题很好判断,只需要看我们在对切片进行操作的时候,完整的列表是否会相应的变化即可。看如下例子:
a_nums = [1,2,3,4,5,6,7]

a = a_nums
a[0:4] = a_nums[0:4][::-1]
print("使用浅复制的测试:")
print(a)
print(a_nums)

#将切片赋值给一个变量
b_nums = [1,2,3,4,5,6,7]
b = b_nums[0:4]
b = b[::-1]
print("将切片复制的测试:")
print(b)
print(b_nums)

c_nums = [1,2,3,4,5,6,7]
c_nums[0:4] = c_nums[0:4][::-1]
print("直接使用切片的测试:")
print(c_nums

输出:
使用浅复制的测试:
[4, 3, 2, 1, 5, 6, 7]
[4, 3, 2, 1, 5, 6, 7]
将切片复制的测试:
[4, 3, 2, 1]
[1, 2, 3, 4, 5, 6, 7]
直接使用切片的测试:
[4, 3, 2, 1, 5, 6, 7]

第一部分,我们使用浅复制将a_nums赋值给a,然后对a的切片进行操作,可以看到同时操作了a_nums。第二部分,我们将b_nums的切片赋值给一个变量,然后对变量进行操作,可以发现,变量的内容翻转了,但是b_nums的内容并没有变化,可见此处变量的值时b_nums切片的复制。第三部分,我们直接对c_nums的切片进行多层切片操作,可以发现nums的内容改变了。

由此得出结论

  1. 切片本身不是一个复制,可以视为对列表自身一部分的截取,在切片上的操作等同于对列表本身的操作。
  2. 当我们将列表的一个切片赋值给一个变量时,变量就得到了一个关于切片的副本,对变量的操作与列表本身无关。
  3. 使用浅复制直接将列表赋值给一个变量时,对该变量的任何操作都等同于直接对列表的操作。
  • 元组
    列表——可修改,适合用于存储在程序运行期间可能变化的数据集。
    元组——不可修改,即元组的值不可变,用于存储不希望被修改的元素。
    元组看起来很像列表,但使用圆括号而非中括号来标识。定义元组之后,就可使用索引来访问元素,就像访问列表元素一样。
    严格的说,元组是由逗号标识的,圆括号知识让元组看起来更整洁、清晰。如果要定义只包含一个元素的元组,必须在这个元祖后面加上逗号。创建只包含一个元素的元组通常没有意义,但自动生成的元组有可能只有一个元素。
    元组的定义:
item = tuple(range(1,10,2))  #可以使用range函数创建元组
print(item)

item2 = (1,2)  #可以直接定义元组
print(item2)

item3 = (3,)  #创建只有一个元素的元组
print(item3)

输出:
(1, 3, 5, 7, 9)
(1, 2)
(3,)

可以像遍历列表一样使用for循环遍历元组

item = tuple(range(1,10,2))  
print(item)

for i in item:
    print(i**2)

输出:
(1, 3, 5, 7, 9)
1
9
25
49
81

虽然不能修改远足的额元素,但是可以给存储元组的变量复制,即不能对元组的元素进行修改,但是可以重新定义整个元组。

item = (1,2)
print(item)

item = (9,10)
print(item)

输出:
(1, 2)
(9, 10)

试图修改元组元素时,会报错:

item = (1,2)
print(item)

item[0] = 6

错误提示:
Traceback (most recent call last):
  File "/Users/liheng/Documents/CODES/Python/test.py", line 4, in <module>
    item[0] = 6
TypeError: 'tuple' object does not support item assignment

总而言之,元组是比列表更简单的数据结构,如果需要存储的一组值在程序的整个生命周期内都不变,就可以使用元组。

  • 获取列表特定元素下标
    • 方法index(value, start, end)
      在范围(start, end)内查找value的下标,如果有多个重复value,会返回第一个值。
    • 方法enumerate(sequence, start)
      对于sequence,从下标start开始,返回(index, value)这样的元组组成的列表。下面for循环中的用法是最常见的。
items = [1,3,5,7,9,3,1]
location_1 = items.index(1,2,) #end出不添加值则是到列表末尾
print(location_1)
location_1 = items.index(1)
print(location_1)

location_2 = list(enumerate(items))
print(location_2)

for i, v in enumerate(items):
    print(i,v)

输出:
6
0
[(0, 1), (1, 3), (2, 5), (3, 7), (4, 9), (5, 3), (6, 1)]
0 1
1 3
2 5
3 7
4 9
5 3
6 1
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值