列表是一个线性的集合,它允许用户在任何位置插入、删除、访问和替换元素。 列表实现是基于数组或基于链表结构的。当使用列表迭代器的时候,双链表结构比单链表结构更快。 有序的列表是元素总是按照升序或者降序排列的元素。

可以这么理解:列表就是一个长度可变的数组

列表不能作为字典的key

常用方法:

index() O(1)
append O(1)
pop() O(1)
pop(i) O(n)
insert(i,item) O(n)
del operator O(n)
iteration O(n)
contains(in) O(n)
get slice[x:y] O(k)
del slice O(n)
set slice O(n+k)
reverse O(n)
concatenate O(k)
sort O(nlogn)
multiply O(nk)

O括号里面的值越大代表效率越低

列表和元组

列表和元组的区别是显然的: 列表是动态的,其大小可以该标 (重新分配); 而元组是不可变的,一旦创建就不能修改。

list和tuple在c实现上是很相似的,对于元素数量大的时候, 都是一个数组指针,指针指向相应的对象,找不到tuple比list快的理由。 但对于小对象来说,tuple会有一个对象池,所以小的、重复的使用tuple还有益处的。

为什么要有tuple,还有很多的合理性。 实际情况中的确也有不少大小固定的列表结构,例如二维地理坐标等; 另外tuple也给元素天然地赋予了只读属性。

列表推导式

[x for x in data if condition]

multiples = [i for i in range(30) if i % 3 == 0]

在列表推导中直接使用了‘LIST_APPEND’这个字节码来实现 append 功能,效率相当的高。而在 for 循环中每次循环都要先载入 append 这个属性然后再 ‘CALL_FUNCTION’一下。这样势必就会慢了很多。

循环删除(坑)


# 使用固定长度循环pop方法删除列表元素
num_list_1 = [1, 2, 2, 2, 3]

for i in range(len(num_list_1)):
    if num_list_1[i] == 2:
        num_list_1.pop(i)
    else:
        print(num_list_1[i])

print("num_list_1:", num_list_1)
# IndexError: list index out of range

原因是在删除list中的元素后,list的实际长度变小了,但是循环次数没有减少,依然按照原来list的长度进行遍历,所以会造成索引溢出

原始的list是num_list,那么其实,num_list[:]是对原始的num_list的一个拷贝,是一个新的list,所以,我们遍历新的list,而删除原始的list中的元素,则既不会引起索引溢出,最后又能够得到想要的最终结果。此方法的缺点可能是,对于过大的list,拷贝后可能很占内存。那么对于这种情况,可以用倒序遍历的方法来实现。

# 遍历拷贝的list,操作原始的list
num_list_4 = [1, 2, 2, 2, 3]

for item in num_list_4[:]:
    if item == 2:
        num_list_4.remove(item)
    else:
        print("item", item)

    print("num_list_4", num_list_4)

print("after remove op", num_list_4)

results matching ""

    No results matching ""