JAYのpython学习笔记——数据结构之列表

python的数据结构分为好几种,包括列表(包含多维列表)、元组、集合、字典。
在本单元,我们主要学习列表和多维列表。
列表可以存储任意大小的数据集合
需要区别的是,在其他的设计语言中,会用到数组来存储一个数据序列,但是数组是有固定的大小的,列表的大小是可变的,可以随需求增大或缩小

列表基础

创建列表

列表是一个用list类定义的序列,包含了创建、操作、处理列表的许多方法,列表的元素可以通过下标来访问。

#语法一
list1 = list()
list2 = list([2, 3, 4])
list3 = list(["red", "green", "blue"])
list4 = list(range(3,6))
list5 = list("abcd")
#语法二,更加简洁一些
list1 = []
list2 = [2, 3, 4]
list3 = ["red", "green"]
list4 = [2, "three", 4] #可以包含同样的元素,也可以包含不一样的元素

列表是一种序列类型

列表与字符串类似,都是序列类型,字符串是字符序列,列表是任意元素的序列,对字符串的操作同样也适用于列表。
序列s的常用操作

操作描述
x in s如果x在s中,则返回true
x not in s如果不在,则返回true
s1+s2连接两个序列
s * n, n * sn个s序列的连接
s [ i ]序列s的第i个元素
s [ i : j ]序列s的 i 到 j-1 的片段
len(s)s的元素个数
min(s)s的最小元素
max(s)s的最大元素
sum(s)s的所有元素之和
for loop在for循环中从左到右反转元素
<、 <=、 >、 >=、!、=比较两个序列

列表使用的函数

>>> list1 = [2, 3, 4, 1, 32]
>>> len(list1)
>>> 5
>>> max(list1)
>>> 32
>>> sum(list1)
>>> 42
>>> import random
>>> random.shuffle(list1) #重排
>>> list1
>>> [4, 1, 2, 32, 3]

下标运算符

mylist(index)

下标范围从0len(mylist)-1

for i in range(len(mylist)):
	myList[i] = i

	mylist = [5.6, 4.5, 3.3, 13.2, 4.0, 34.33, 34.0, 45.45, 99.993, 11123]
	#下标范围从0到9,0对应5.6,9对应11123

禁止越界访问列表,否则会返回一个IndexError的错误,确定访问下标没有超过 len(mylist)-1,另外python的列表下标是从0开始的,不是从1开始,这种错误一般被称为“差一错误",在循环中也要注意使用 <<=

i = 0
while i <= len(myList): #应该用<而不是<=
	print(myList[i])
	i += 1

另外,python允许使用负数来表示元素相对于列表末尾的位置

>>> list1 = [2, 3, 5, 2, 33, 21]
>>> list1[-1] #list1[-1]相当于list1[-1+len(list1)]
21

列表截取

list[start : end] 指的是由 list[start : end-1] 的元素构成的子列表

>>> list1 = [2, 5, 9, 7, 1]
>>> list1[2 : 4]
[9, 7]
>>> list1[: 4]
[2, 5, 9, 7]
>>> list1[3 :] 
[7, 1]

起始下标和结尾下标可以省略,起始下标默认为0,结尾下标默认为len(list),可以在截取中使用负数下标,负数下标的等效换算见上述,需要满足的规则是 start<end,不能大于等于,否则将返回一个空表

+、*、in/not in运算符

>>> list1 = [2, 3]
>>> list2 = [1, 9]
>>> list3 = list1 + list2
>>> list3
[2, 3, 1, 9]
>>>
>>> list4 = 2 * list2
>>> list4
[1, 9, 1, 9]
>>> 3 in list3
True

for循环遍历

for u in myList: #访问列表中的每个元素,不用加下标
	print(u)

for i in range(0, len(myList), 2): #访问列表中的奇数位置的元素
	print(myList[i])

比较列表

比较使用的是字典顺序,即首先比较前两个元素,不同就决定了比较的结果,若相同,就比较接下来的两个元素,一直重复,直至比完所有元素。另外,字符串也可以比较,比较字符串的话,就比较他们的Unicode值orASCII值,python中,字符串是用Unicode编码表示的,占用两个字节,ASCII码占用一个字节。

>>> list1 = ["green", "red", "blue"]
>>> list2 = ["red", "blue", "green"]
>>> list2 = list1
False
>>> list2 >= list1
True

列表解析

>>> list1 = [x for x in range(5)]
>>> list1
[0, 1, 2, 3, 4]
>>> list2 = [0.5 * x for x in list1]
>>> list2
[0.0, 0.5, 1.0, 1.5, 2.0]
>>> list3 = [x for x in list2 if x < 1.5]
>>> list3
[0.0, 0.5, 1.0]

列表方法

>>> list1 = [2, 3, 4, 1, 32, 4]
>>> list1.append(19)
>>> list1
[2, 3, 4, 1, 32, 4, 19]
>>> list1.count(4)
2
>>> list2 = [99, 54]
>>> list1.extend(list2)
>>> list1
[2, 3, 4, 1, 32, 4, 19, 99, 54]
>>> list1.index(4) #返回第一次出现该元素的下标
2
>>> list1.insert(1, 25) #将元素25插入下标1处,注意列表的起始下标是0
>>> list1 
[2, 25, 3, 4, 1, 32, 4, 19, 99, 54]
>>> list1.pop(2) #删除给定位置的元素并返回它,如果不指定,那么就删除最后一个元素
3
>>> list1
[2, 25, 4, 1, 32, 4, 19, 99, 54]
>>> list1.pop()
54
>>> list1.remove(32)
>>> list1
[2, 25, 4, 1, 4, 19, 99]
>>> list1.reverse() #
>>> list1
[99, 19, 4, 1, 4, 25, 2]
>>> list1.sort() #从小到大排序
>>> list1
[1, 2, 4, 4, 19, 25, 99]

将字符串分成列表

items = "Jane John Peter Susan".split()
#会将列表分成['Jane', 'John', 'Peter', 'Susan']
#可见这个分隔是以空格分隔的
items = "09/20/2012".split("/")
#会将字符串分隔成['09', '20', '2012']

输入列表

lst = []
print("Enter 10 number:")
for i  in range(10):
	lst.append(eval(input()))
#从控制台中输入10个数字,并将其追加至列表
#read numbers as s string from the console
s = input("Enter 10 numbers seperated by spaces from one line:")
items = s.split() #extract items from the string
lst = [eval(x) for x in items] #convert items to numbers

对列表移位

python中没有提供移位的方法,可以自己实现

def shift(lst):
	temp = lst[0] #retain the first element
	 
	#shift elements left
	for i in range(1, len(lst))
		lst[i-1] = lst[i]

	#move the first element to fill in the last position
	lst[len(lst) - 1] = temp

简化代码

列表可以大大的简化某些任务,例如通过输入数字来返回月份

months = ["January", "February", "March", ..., "December"]
monthNumber = eval(input("Enter a month number (1 to 12): "))
print("The month is", months[monthNumber - 1])

将列表传递给函数

由于列表是一个可变对象,当列表被传递给函数之后,列表的内容可能发生变化

def printList(lst):
	for element in lst:
		print(element)

printlist([3, 1, 2, 6, 4, 2]) #创建一个列表,但是没有显示的指向列表的引用变量,这样的列表称为匿名变量
#PassListArgument.py
def main():
	x = 1 #x is an int variable
	y = [1, 2, 3]
	
	m(x, y)
	
	print("x is", x)
	print("y[0] is", y[0])

def m(number, numbers):
	number = 1001
	numbers[0] = 5555

main()
x is 1
y[0] is 5555

在这个案例中,m被调用之后,x保持为1,但是y[0]的值改变了,numbers指向的就是列表的引用值,但是number是不可变的,所以在函数中改变它,会创建一个新的实例,函数外的原始实例并没有发生变化,即外部的x依旧是1。

#DefaultListArgument.py
def add(x, lst = []):
	if x not in lst:
	lst.append()

	return list

def main():
	list1 = add(1)
	print(list1)

	list2 = add(2)
	print(list2)

	list3 = add(3,[11, 12, 13, 14])
	print(list3)

	list4 = add(4)
	print(list4)

main()
[1]
[1, 2]
[11, 12, 13, 14, 3]
[1, 2, 4]

如果lst不在参数列表中,那么lst的默认值[]自动创建,且只会被创建一次,当函数被再次调用时,那么列表lst就是之前被创建并被修改后的 [1],执行函数之后,变成了 [1, 2],给出了创建的列表的话,那么就对创建的列表进行函数操作,否则还是对默认列表进行操作。

#需要每次创建列表都是空列表的话,可以做如下修改
def add(x, lst = None):
	if lst == None:
		lst = []
	if x not in lst:
		lst.append(x)

	return list

def main():
	list1 = add(1)
	print(list1)

	list2 = add(2)
	print(list2)

	list3 = add(3,[11, 12, 13, 14])
	print(list3)

	list4 = add(4)
	print(list4)

main()
[1]
[2]
[11, 12, 13, 14, 3]
[4] 

从函数返回一个列表

当函数返回一个列表时,就会返回这个列表的引用值

def reverse(lst):
	result = []

	for element in lst:
		result.insert(0, element)

	return result

# list1 = [1, 2, 3, 4, 5, 6]
# list2 = reverse(list1) 
# list2 返回值为6,5, 4, 3, 2, 1 

多维列表

一张表或者一个矩阵的数据可以存储在二维列表中
二维列表是将其他列表作为它元素的列表

处理二维列表

二维列表中的值可以通过行下标和列下标来访问
可将二维列表理解为一个由行组成的列表,每一行的值又构成一个列表。
matrix = [
[1, 2, 3, 4, 5],
[6, 7, 0, 0, 0],
[0, 1, 0, 0, 0],
[1, 0, 0, 0, 8],
[0, 0, 9, 0, 3]
]
matrix[0] is [1, 2, 3, 4, 5]
matrix[1] is [6, 7, 0, 0, 0]
matrix[2] is [0, 1, 0, 0, 0]
matrix[3] is [1, 0, 0, 0, 8]
matrix[4] is [0, 0, 9, 0, 3]
matrix[0][0] is 1
matrix[4][4] is 3

使用输入值初始化列表

matrix = []

numberOfRows = eval(input("Enter the number of rows:"))
numberOfColumns = eval(input("Enter the number of columns:"))
for row in range(numberOfRows):
	for column in range(numberOfColumns):
		value = eval(input(:"Enter an element and press Enter:"))
		matrix[row].append(value)

print(matrix)

使用随机数初始化列表

import random

matrix = []

numberOfRows = eval(input("Enter the number of rows:"))
numberOfColumns = eval(input("Enter the number of columns:"))
for row in range(numberOfRows):
	matrix.append([])
	for column in range(numberOfColumns):
		matrix[row].append(random.randint(0,99))

print(matrix)

打印列表

matrix = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]

for row in range(len(matrix)):
	for column in range(len(matrix[row])):
		print(matrix[row][column],end = "")
	print()#print a new line

另一种写法:

matrix = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]

for row in matrix:
	for value in row:
		print(value, end = "")
	print()

对所有元素求和

matrix = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]

total = 0
for row in matrix:
	for value in row:
		total += value

print("Total is", total)

按列求和

matrix = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
for column in range(len(matrix[0])):
	total = 0
	for row in range(len(matrix)):
		total += matrix[row][column]
	print("Sum for column", column, "is", total)

找出和最大的行

matrix = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
maxRow = sum(matrix[0])
indexOfMaxRow = 0

for row in range(1,len(matrix)):
	if sum(matrix[row]) > maxRow:
		maxRow = sum(matrix[row])		#每算一行就更新一次值
		indexOfMaxRow = row

print("Row", indexOfMaxRow, "has the maximum sum of", maxRow)

随意打乱

随几生成下标i和j,再将matrix[row][column]和matrix[i][j]进行互换

import random
matrix = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
for row in range(len(matrix)):
	for column in range(len(matrix[row])):
		i = random.randint(0, len(matrix) - 1)
		j = random.randint(0, len(matrix[row]) - 1)

		matrix[row]column],matrix[i][j] = matrix[i][j], matrix[row][column]

print(matrix)

排序

通过对每一行第一个元素排序,对于第一个元素相同的行,再对第二个元素进行排序,若都相同,则对第三个元素进行排序,依此类推

>>> points = [[4, 2], [1, 7], [4, 5], [1, 2], [1, 1], [4, 1]]
>>> points.sort()
>>> print(points)
[[1, 1], [1, 2], [1, 7], [4, 1], [4, 2], [4, 5]]

将二维列表传递给函数

def getMatrix():
	matrix = []
	
	numberOfRows = eval(input("Enter the number of rows:"))
	numberOfColumns = eval(input("Enter the number of columns:"))
	for row in range(numberOfRows):
		matrix.append([])
		for column in range(numberOfColumns):
			value = eval(input("Enter a value and press Enter:"))
			matrix[row].append(value)

	return matrix
# 提示用户输入矩阵的元素值,并返回这个列表
def  accumulate(m):
	total = 0
	for row in m:
		total += sum(row)
	
	return total
# 返回列表所有元素的总和
def main():
	m = getMatrix()
	print(m)

	print("\nSum of all elements is ", accumulate(m))

main()

多维列表

一个多维列表是每个元素是其他列表的列表。例如,一个三维列表是由二维列表组成的列表,而一个二维列表是由一维列表构成的列表。
案例:每日温度和湿度
假设一个气象站纪录了每天每个小时的温度和湿度并且将过去十天里的温度和湿度数据存储到一个txt文件中,文件中的每一行含有四个数字,分别表示日期、时间、温度和湿度,如下所示。
1 1 76.4 0.92
1 2 77.7 0.93
……
10 23 97.7 0.71
编写一个程序计算这十天的平均温度和湿度,可以使用 输入重定向 来从文件中读取数据并将这些数据保存在一个名为data的三维列表中,data的第一个下标范围在0-9,第二个下标的范围在0-23,第三个下标取0or1,表示温度和湿度,所以data[0][0][0]存储的是第一天1点时的温度,data[9][23][1]存储的是第十天24点的湿度。

#Weather.py
def main():
	NUMBER_OF_DAYS = 10
	NUMBER_OF_HOURS = 24

	#Initialize data
	data = []
	for i in range(NUMBER_OF_DAYS):
		data.append([])
		for j in range(NUMBER_OF_HOURS):
			data[i].append([])
			data[i][j].append(0) #温度值
			data[i][j].append(0) #湿度值

	#Read input using input redirection from a file
	for k in range(NUMBER_OF_DAYS * NUMBER_OF_HOURS):
		line = input().strip().split() # .strip 去除首位字符(默认是空格或者换行符)
		day = eval(line[0])
		hour = eval(line[1])
		temperature = eval(line[2])
		humidity = eval(line[3])
		data[day - 1][hour - 1][0] = temperature
		data[day - 1][hour - 1][1] = humidity

	# Find the average daily temperature and humidity
	for i in range(NUMBER_OF_DAYS):
		dailyTemperatureTotal = 0
		dailyHumidityTotal = 0
		for j in range(NUMBER_OF_HOURS):
			dailyTemperatureTotal += data[i][j][0]
			dailyHumidityTotal += data[i][j][1]

	#display result
	print("Day " + str(i) + "'s average temperature is " + str(dailyTemperatureTotal / NUMBER_OF_HOURS))
	print("Day " + str(i) + "'s average humidity is " + str(dailyHumidityTotal / NUMBER_OF_HOURS))

main()
#可以使用下面的命令来运行程序
python Weather.py < Weather.txt
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值