二、列表
今天在工作中涉及到列表的处理,非常简单的数据类型,但是处理起来或遇到各种问题,需要格外小心。
更新的内容主要包括列表的定义,增加,删除元素,条件判断去除列表元素,以及列表最大值,最小值,平均值的获得
2.1 列表初步
在python中,列表的关键字是list,其中可以包含任意的元素,最简单的便是一维列表,即列表的每个元素都是单纯的数据元素,而不是其他的数据类型。在此之上,列表中的每个元素也可以是列表,因此,嵌套之下,可以有二维列表、三维列表等等。此外,列表中的每个元素也可以是字典,就更为复杂一点。总之,列表直接看起来是一个简单的数组,但是在应用的时候,会有很多的变化,涉及到许多复杂的处理。
给出列表的基本代码:
#!python3.7.9
def list_show():
list_example = [1, 2, 3, 4, 5]
print(list_example)
if __name__ == '__main__':
list_show()
上述代码给出了一个list_example的列表,最终把它直接打印在控制台。这里主要有两个点:一个是list_example变量,并没有声明,是直接赋值操作的,python支持这样做,但复杂场景需要小心;另外一个就是python中的print函数不同于C语言,可以识别列表变量,将其打印出来。
2.1 列表中增加元素
列表的主要应用是收集,处理数据。因此,灵活的根据条件,向列表中增加元素是必须掌握的技能。
考虑如下的场景,假设另外有一个列表list_demo,里面存放着[5,6,7,8,9,10],一共6个数据。现在需要分别完成如下的要求:
- 将list_demo中的数据全部放入list_example中
- 将list_demo中小于8的数据全部放入list_example中
- 将list_demo中小于8,且list_example中没有的数据放入list_example,而list_example中有的数据则不必放入
给出实现的代码
#!python3.7.9
def list_show():
list_example = [1, 2, 3, 4, 5]
print(list_example)
list_demo = [5, 6, 7, 8, 9, 10]
# Request 1
# incorrect: list_demo as a element in list_example
#list_example.append(list_demo)
# correct 1
#for i in list_demo:
# list_example.append(i)
# correct 2
#list_example.extend(list_demo)
# Request 2
# correct 1
#for i in list_demo:
# if i < 8:
# list_example.append(i)
# Request 3
# correct 1
for i in list_demo:
if i < 8 and i not in list_example:
list_example.append(i)
print(list_example)
if __name__ == '__main__':
list_show()
上述代码给出了三种要求的基本实现,同时给出了一种错误的示范,重点便在于这个错误,即是append方法的特殊性*(注:方法函数不同,可以先简单的将跟在变量后的操作称之为方法)*。append方法会将其包含的数据,作为一个元素,直接添加在目的列表中,因此,一次append方法,仅仅会在目的列表中添加一个元素。**代码结果更为直观,执行上述15行的代码之后,可以得到list_example中仅仅多了一个元素,而这个元素正是list_demo本身。**这显然不是我们所要求的结果。这另一方面显示了list中元素的灵活性,也提醒使用者,向列表中添加元素的时候要特别小心。
1.2 列表中删除元素
这个是我今天工作遇到的一个非常重要的bug,但不易被察觉到。
考虑如下的2种需要对列表list_example删除元素的场景:
- 删除list_example中第一个元素
- 删除list_example中所有小于3的元素
给出实现的代码
#!python3.7.9
import pdb
def list_show():
list_example = [1, 2, 3, 4, 5]
# Request 1
# correct 1
#list_example.pop(0)
# incorrect 1
#list_example.pop(1)
# correct 2
#list_example.remove(1)
# incorrect 1
#list_example.remove(0)
# Request 2
# incorrect 1
#for i in list_example:
# if i < 3:
# list_example.pop(i)
# incorrect 2
#for i in list_example:
# if i < 3:
# list_example.remove(i)
# correct 1
#for i in range(len(list_example) - 1, -1, -1):
# if list_example[i] < 3:
# list_example.pop(i)
# correct 2
#for i in range(len(list_example) - 1, -1, -1):
# if list_example[i] < 3:
# list_example.remove(list_example[i])
# correct 3
list_example = [ x for x in list_example if x >= 3]
print(list_example)
if __name__ == '__main__':
list_show()
前两种错误的问题都处于一点:在循环时候,删除列表中的元素,列表会直接更新,而不会维持等到循环结束才更新,因此,在删除元素的前后,列表的数据及其位置会向前发生变化,因此得不到期待的数据。这个机制很隐蔽,很有可能发生了bug的时候,还无法感觉,因此很有可能非常致命。
解决方法也很简单,既然列表数据的位置是向前更新,我们可以从列表尾端向前遍历,进行删除,也就是上述代码所列出的第一种和第二种方法,for循环range的参数可以灵活设置,但本质还是从后向前遍历。
第三种方法,相当于把整个list先清空,再把想要的数据放到原本的list中,这里句子语法略有点不好理解,但也不好拆开了,可以看作是一种固定的用法把。
1.3 最值 & 平均值
这部分内容非常简单,最值可以直接利用min,max函数直接得到。平均值可以采用遍历元素的方式,也可以直接调用numpy模块的方法直接获得。
直接给出处理list_example列表的代码:
#!python3.7.9
import numpy as np
def list_show():
list_example = [1, 2, 3, 4, 5]
min_value = min(list_example)
max_value = max(list_example)
mean_value = np.mean(list_example)
print(list_example)
print("min = %d, max = %d" % (min_value, max_value))
print("mean = %d" % mean_value)
if __name__ == '__main__':
list_show()
其实对于数据集合的处理,平均值中有很大的学问,这里的mean只是简单的做了一个算数平均,还有几何平均,中位数,众数标准偏差等等相关的概念。想要得到一个可以代表集合的数据,是一件不容易的事。二当数据量巨大的时候,会趋近于正态分布,进而有相关的概率统计知识,是一个很好的适合研究的东西。
正态分布图真的非常漂亮。