关于List:
- 最最最基本操作
- 其他操作上的问题
- 一、如何判断 list 重复
- 二、根据 list 里面的每一个 list 的第一个元素排序
- 三、 一个 list 给另一个 list 赋值
- 四、list 与 nparray
- 五、二维列表按列取元素
- 报错汇总
- IndexError:list assignment Index out of range
- ValueError: invalid literal for int() with base 10: "6960"
- TypeError: unhashable type: 'list'
- List的效率问题(处理大数据时尤为重要)
最最最基本操作
# 创建
L = []
L = ['a', 'b', 'c']
L = ['apple', 123, True]
L = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
L = list(range(5))
# 取长度
len(L)
# 插入
L.insert(2, 'd') # 在指定位置插入元素
L.append('pear') # 在尾部追加元素
# 删除
L.pop() # 删除尾部元素
L.pop(1) # 删除指定位置元素
L.remove('a') # 删除指定元素
# 元素替换
L[0] = 'banana'
# 求元素出现次数
L.count('apple')
# 取元素索引
L.index('apple')
# 元素排序
L.sort()
L.sort(reverse = True)
# List切片操作(正数--索引,负数--位)
a = [1,2,3,4,5,6]
print(a[2:4]) # [3, 4] 左闭右开区间 从索引2到索引4
print(a[-4:-2]) # [3, 4] 左闭右开区间 从倒数第4位到倒数第3位
print(a[:4]) # [1, 2, 3, 4] 默认从索引0开始开始
print(a[4:]) # [5, 6] 默认到最大索引结束
print(a[::1]) # [1, 2, 3, 4, 5, 6] 从索引0开始每1位输出一次
print(a[::2]) # [1, 3, 5] 从索引0开始每2位输出一次
print(a[::-1]) # [6, 5, 4, 3, 2, 1] 从最后一位开始,倒序每1位输出一次
print(a[::-2]) # [6, 4, 2] 从最后一位开始,倒序每2位输出一次
其他操作上的问题
一、如何判断 list 重复
l1 = [1,2,3]
l2 = [3,2,1]
print(l1 == l2) # False:l1 和 l2 逐个元素进行比较,相同位置元素全都相同认为 list 相同
print(set(l1) == set(l2)) # True:l1 和 l2 含有的元素相同即认为 list 相同
二、根据 list 里面的每一个 list 的第一个元素排序
arr_new = [ [2,3,4] , [3,4,5], [1,2,3] ]
sort_arr = [value for index, value in sorted(enumerate(arr_new), key=lambda arr_new: arr_new[1])]# sort_arr = [ [1,2,3] ,
# [2,3,4],
# [3,4,5] ]
三、 一个 list 给另一个 list 赋值
方式一: 直接用 =
赋值,实际是把对象 a 的地址给了 b(即 a 和 b 指向内存中相同的位置),所以对 a 做修改,b 也表现为被修改了。
a = [1, 2, 3]b = a
# b = [1, 2, 3]a[0] = 0
# b = [0, 2, 3]
方式二:使用切片
赋值,实际上为 b 重新开辟了一块内存区域,用 a 的每一个元素的值来给 b 赋值,由于a 、b 在内存中的指向不同,所以修改 a 对 b 并没有影响
b = a[:]
a[0] = 0
b = [1, 2, 3]
四、list 与 nparray
术语:
- list 是
列表
,列表的元素是列表可以称为多层列表,list最多只有一个维度,是python内置对象
。 - nparray 是
数组
,真正的数组,可以有多个维度,是numpy的数据类型
。
1、关于list 转 nparray
真是一部血泪史!!!!(在此感谢高中同学GL的帮助)
list1 = [[1, 2, 3], [4, 5, 6]]
nparr1 = np.array(list1)
# 结果 nparr1 变成了二维数组,很棒对不对!!!
[[1 2 3][4 5 6]]# 但是我当时就转不过来,才发现是list的问题
list2 = [[1, 2, 3], [4, 5]]
nparr2 = np.array(list2)
# 结果 nparr2 是这样子的:
[list([1, 2, 3]) list([4, 5])]
数据处理的时候忽略了一种情况,导致这个 bug,其实这个bug又会引起别的地方的 bug,使用 debug 的方式一步步向上找,才找到问题得根源,debug 大法好!
也说明了在写程序的时候,写一段就 test 一段会比较好,一不小心留下的小问题,到最后需要很大力气回来找原因。
2、nparray 转 list
b = np.array([[1, 2, 3], [4, 5, 6]])
a = b.tolist()
# 结果 b:
[[1 2 3][4 5 6]]
# 结果 a:
[[1, 2, 3], [4, 5, 6]]
3、展开
# 1、二维数组转化为一维数组
b = np.array([[1, 2, 3], [4, 5, 6]])
b = b.reshape((1, -1))
# 结果:
[[1 2 3 4 5 6]]# 2、多层 list 展平为一层
a = [[1, 2, 3], [4, 5, 6]]
a_flat = [item for sublist in a for item in sublist]
# 结果
[1 2 3 4 5 6]
# 更多展开方法见:https://www.cnblogs.com/wushaogui/p/9241931.html
五、二维列表按列取元素
直接切片是不行的:
a=[[1,2,3], [4,5,6]]
print(a[:, 0]) # 尝试用数组的方法读取一列失败
我们可以直接构造:
b = [i[0] for i in a] # 从a中的每一行取第一个元素。
print(b) # [1, 4]
报错汇总
IndexError:list assignment Index out of range
情况一:数组索引越界
情况二:数组未初始化
报错代码如下:
temp = []
for line in friend_arr:if (line[0] in u_dict) and (line[1] in u_dict):temp[0] = u_dict.get(line[0])temp[1] = u_dict.get(line[1])friend_arr_new.append(temp)
改为 temp = [0, 0]
注意后面是根据索引赋值,而不是根据append添加值,所以初始化时不能为空。
其实可以不用临时变量,改为:
for line in friend_arr:if (line[0] in u_dict) and (line[1] in u_dict):friend_arr_new.append([u_dict.get(line[0]), u_dict.get(line[1])])
ValueError: invalid literal for int() with base 10: “6960”
错误含义:应该放一个 int 类型的数据,我放了一个无效的字符 “6960”
去看一下报错那行的变量是下面这样的,把string放了进去,找到赋值的地方,去掉了str(),
[23,56,78,'70,'70','70']
网上也有人说可以这样操作,不过我这里是不需要:
import re
# 用了int(string)语句的地方改为下面的表达,即去掉所有非数字的字符。
int(re.sub("\D","",string))
TypeError: unhashable type: ‘list’
1、原因:set的元素必须是可以hash的元素(hashable items)
- int、float、str、tuple:是可以哈希的
- list、set、dict:是不可哈希的
s = {1, 2} # 使用元素直接创建set集合(此时元素为int类型)
print(s)
s1 = set([1, 2]) # 使用list中的元素创建set集合(此时list中的元素为int类型)
print(s1)
结果:
{1, 2}
{1, 2}
s2 = {[1, 2], [1, 2], [1, 2, 3]} # 使用元素直接创建set集合(此时元素为list类型)
print(s2)s3 = set([[1, 2], [1, 2], [1, 2, 3]]) # 使用list中的元素创建set集合(此时list中的元素为list类型)
print(s3)
结果:
TypeError: unhashable type: ‘list’
TypeError: unhashable type: ‘list’
2、一般使用 set 里面放 list 的目的是想获得不重复的 list 的集合
# 换个思路:list中元素都排序后就可以识别重复
list_temp.sort()
if list_temp not in list_total:list_total.append(list_temp)
List的效率问题(处理大数据时尤为重要)
1、检查元素
与字典、集合相比,检查列表中元素是否存在某个值是非常缓慢的,这是因为Python在列表中进行了线性逐个扫描,而在字典和集合中Python是同时检查所有元素的(基于哈希表)
2、连接列表
x = [‘a’, ‘b’, ‘c’]
y = [‘apple’, 123, True]
方式一:x+y
方式二:x.extend(y)
方式一是一种相对高代价的操作,因为连接过程中创建了新列表,并且需要复制对象。
方式二是一种效率更高的操作,尤其是在构建大型列表的时候。