引言
今天来梳理一下 Python list 列表的知识点,更多 Python 基础系列文章,请参考 Python 基础系列大纲
内容提要:
- List 列表的特性
- list 创建
- List Python 思维 – 返回 list
- List 操作 & 方法
访问 access
查询 query
更新 update
删除 delete - 内存引用和垃圾回收
- list 遍历
- list 拷贝 COPY
- list 性能
- 练习
List 列表的特性
List 是一个可变的异类对象的有序集合
-
可变有序集合 a mutable sequence
-
改变 value 内存地址不会改变 Memory address (id()) does not change after changing the values
-
对象没有限制,异类,不唯一 no restrictions: heterogeneous-types, non-unique
举例:对象不唯一
list_object = ['name', 'kelly', 'name', 'peter', 'name', 'Bob']
print(list_object)
# output: ['name', 'kelly', 'name', 'peter', 'name', 'Bob']
举例:对象异类:
可以是 function 类
# str, list, int
list_object1 = ['hello world', ['kelly', 'peter'], 2020]
# tuple, dict, function
list_object2 = [('kelly', 'peter'), {(17, 18, 19): 'age group'}, print]
print(list_object1)
print(list_object2)
# output:
# ['hello world', ['kelly', 'peter'], 2020]
# [('kelly', 'peter'), {(17, 18, 19): 'age group'}, <built-in function print>]
举例:可变: 可改变 value, id 不变,没有新对象生成,还是同一个对象
str_object = 'kelly'
list_object = list(str_object)
print('\t id: {}, \t list content: {}'.format(id(list_object), list_object))
def delete_first(list_arg):
del list_arg[0]
delete_first(list_object)
print('\t id: {}, \t list content: {}'.format(id(list_object), list_object))
# output:
# id: 2239125883072, list content: ['k', 'e', 'l', 'l', 'y']
# id: 2239125883072, list content: ['e', 'l', 'l', 'y']
list 创建
- 空 List:
lst = list()
lst = [] - 强制类型转换 via coercion of another object:
lst = list(another_object)
lst = [another_object]
code: tuple to list:
t = ('script', 'python')
lst_via_constructor = list(t)
lst_via_symbol = [t]
print('tuple to list via constructor:\nlist length:{}\tlist content:{} '.format(len(lst_via_constructor ), lst_via_constructor ))
print('tuple to list via symbol:\nlist length:{}\tlist content:{} '.format(len(lst_via_symbol), lst_via_symbol))
# output:
# tuple to list via constructor:
# list length:2 list content:['script', 'python']
# tuple to list via symbol:
# list length:1 list content:[('script', 'python')]
code: dict to list
d = {'script': 'python'}
lst_via_constructor = list(d)
lst_via_symbol = [d]
print('dict to list via constructor:\nlist length:{}\tlist content:{} '.format(len(lst_via_constructor ), lst_via_constructor ))
print('dict to list via symbol:\nlist length:{}\tlist content:{} '.format(len(lst_via_symbol), lst_via_symbol))
# output:
# dict to list via constructor:
# list length:1 list content:['script']
# dict to list via symbol:
# list length:1 list content:[{'script': 'python'}]
code: set to list
s = {'script', 'python'}
lst_via_constructor = list(s)
lst_via_symbol = [s]
print('set to list via constructor:\nlist length:{}\tlist content:{} '.format(len(lst_via_constructor ), lst_via_constructor ))
print('set to list via symbol:\nlist length:{}\tlist content:{} '.format(len(lst_via_symbol), lst_via_symbol))
# output:
# set to list via constructor:
# list length:2 list content:['python', 'script']
# set to list via symbol:
# list length:1 list content:[{'python', 'script'}]
code: str to list
str_object = 'python'
lst_via_constructor = list(str_object)
lst_via_symbol = [str_object]
print('str to list via constructor:\nlist length:{}\tlist content:{} '.format(len(lst_via_constructor ), lst_via_constructor ))
print('str to list via symbol:\nlist length:{}\tlist content:{} '.format(len(lst_via_symbol), lst_via_symbol))
# output:
# str to list via constructor:
# list length:6 list content:['p', 'y', 't', 'h', 'o', 'n']
# str to list via symbol:
# list length:1 list content:['python']
List Python 思维 – 返回 list
Code:
new_list = [x.lower() for x in ['A', 'B', 'C', 'D']]
print(new_list)
# output:
# ['a', 'b', 'c', 'd']
List 操作 & 方法
访问 Access
注意如果如果 index 越界,则会抛出 IndexError: Index out of range
lst = [ 1, 2, 3 ]
index = 2
lst [ index ] = 5
lst
# output:
# [1, 2, 5]
查询 Query
操作符 in
用来检查从属关系,返回 Ture 或 False
info_list = ['kelly', 'peter']
is_kelly_in = 'kelly' in info_list
is_bob_in = 'Bob' in info_list
print('is kelly in info_list: {}'.format(is_kelly_in))
print('is bob in info_list: {}'.format(is_bob_in))
# output:
# is kelly in info_list: True
# is bob in info_list: False
更新 Update
拼接:用 +
操作符或 .extend()
函数
重复复制用 *
操作符
Code:
group_a = ['Ann', 'Arthur']
group_b = ['Bob', 'Bred']
newGroup = group_a + group_b
group_a.extend(group_b)
print ('Concatenation using ‘+’ operator: {}'.format(newGroup))
print ('Concatenation using .extend(): {}'.format(group_a))
print ('Repetition using * operator: : {}'.format(group_b * 3))
# output:
# Concatenation using ‘+’ operator: ['Ann', 'Arthur', 'Bob', 'Bred']
# Concatenation using .extend(): ['Ann', 'Arthur', 'Bob', 'Bred']
# Repetition using * operator: : ['Bob', 'Bred', 'Bob', 'Bred', 'Bob', 'Bred']
insert(index, value) 和 append(value) 方法
insert 是根据 index 进行插入
append 总是 list 最后追加
str_object = 'python'
list_object = list(str_object)
print('original list content: \n{}'.format(list_object))
list_object.insert(2, 'A')
print('list content after insert: \n{}'.format(list_object))
list_object.append('S')
print('list content after append: \n{}'.format(list_object))
# output:
original list content:
['p', 'y', 't', 'h', 'o', 'n']
list content after insert:
['p', 'y', 'A', 't', 'h', 'o', 'n']
list content after append:
['p', 'y', 'A', 't', 'h', 'o', 'n', 'S']
删除 Delete
remove(value): 从 list 头部查找到 value,删除一次
clear():清空 list 内容
pop([index]) :按 index 移除 item,如果 pop() 则是移除 list 尾部最后一个 item
del list[index] :按 index 删除 list 中的 item
代码:
name_list = ['kelly', 'peter','peter', 'bob', 'bruce']
print('orignal list content:\n{}'.format(name_list))
name_list.remove('peter')
print('content after remove peter:\n{}'.format(name_list))
name_list.pop(1)
print('content after pop(1):\n{}'.format(name_list))
name_list.pop()
print('content after pop():\n{}'.format(name_list))
name_list.clear()
print('content after clear:\n{}'.format(name_list))
# output:
orignal list content:
['kelly', 'peter', 'peter', 'bob', 'bruce']
content after remove peter:
['kelly', 'peter', 'bob', 'bruce']
content after pop(1):
['kelly', 'bob', 'bruce']
content after pop():
['kelly', 'bob']
content after clear:
[]
内存引用和垃圾回收
下面几组例子对说初学者来说是容易出错的,对非基础类型的对象(如 str, list。。。)赋值其实是将另一个对象的内存地址的引用赋值给该对象,意味着该对象对另外一个对象拥有管理权。
a = [1,2,3]
b = a
a = [4,5,6]
print('a list content : {}'.format(a))
print('b list content : {}'.format(b))
语句1:a 指向 [1,2,3] 的内存引用;
语句2: a 指向的引用赋值给 b;
语句3: a 又指向新的内存引用 [4,5,6]
b 没有变化还是指向 [1,2,3]
# output:
a list content : [4, 5, 6]
b list content : [1, 2, 3]
a = [1,2,3]
b = a
a.clear()
a = [4,5,6]
print('a list content : {}'.format(a))
print('b list content : {}'.format(b))
语句1:a 指向 [1,2,3] 的内存引用;
语句2: a 指向的引用赋值给 b;
语句3:将 a 指向的对象 [1,2,3] 清空;
语句4:a 指向另外一个对象 [4,5,6]
b 还是指向原来 [1,2,3] 对象的引用,只是内容被清空了
a list content : [4, 5, 6]
b list content : []
有了前面的基础,下面这个应该很容易了吧,哈哈!
a = [1,2,3]
b = a
a = [4,5,6]
a.clear()
print('a list content : {}'.format(a))
print('b list content : {}'.format(b))
# output:
a list content : []
b list content : [1, 2, 3]
List 遍历
By-item:for item in list_obj:
By index-item pair:for index, item in enumerate(list_obj) :
By-index: for index in range(start_index, end_index, stride) :
通过 in
操作符和 reversed()
函数遍历
代码:
name_str = 'one'
list_obj = list (name_str)
for item in list_obj:
print ( item.upper())
print('Reversed: from end to start')
for item in reversed(list_obj):
print(item.upper())
# output:
O
N
E
Reversed: from end to start
E
N
O
遍历多个 list 用 zip()
name_list = ['kelly', 'peter']
city_list = ['Shanghai', 'Beijing']
for name, city in zip(name_list, city_list):
print('{0} works in {1}'.format(name, city))
# output:
kelly works in Shanghai
peter works in Beijing
通过Index, Item Pair 遍历利用 enumerate()
name_str = 'one'
list_obj = list (name_str)
for index, item in enumerate(list_obj):
list_obj[index] = item.upper()
print(list_obj)
# output:
# ['O', 'N', 'E']
通过 Index 遍历利用 range()
name_str = 'one'
list_obj = list (name_str)
for index in range(0, len(list_obj)):
list_obj[index] = list_obj[index].upper()
print(list_obj)
# output:
['O', 'N', 'E']
list 拷贝 COPY
浅拷贝,内存地址会不一样
Slicing ( [ : ] )
Constructor( list() )
list_obj = [1,2,3]
list_copy = list_obj[:]
object_copy = list(list_obj)
print('original list:\nid:{}\tlist content:{}'.format(id(list_obj), list_obj))
print('list copy:\nid:{}\tlist content:{}'.format(id(list_copy), list_copy))
print('object copy:\nid:{}\tlist content:{}'.format(id(object_copy), object_copy))
内容是一样的,但是id不一样,是不同的对象
# output:
original list:
id:2239126915200 list content:[1, 2, 3]
list copy:
id:2239126870592 list content:[1, 2, 3]
object copy:
id:2239125951424 list content:[1, 2, 3]
list 性能 Performance
性能优:
- 存储异类对象集
- append 追加新的 item
- 基于 index 更新或替换 item
- 移除或删除最近的 item
- 遍历整个 list 或 子 list
性能差:
- 基于 index 插入 insert 一个新的 item
- 基于任意的 index 移除或删除 item
- 用 in 操作符查询存在关系
- list 排序
- 拷贝 list 成一个新的 list 或在不改变原 list 情况下创建一个排序 list 的拷贝
练习
检验学习成果的时候到了,你能答对么