2017/10/9
序列,列表(生成,常用方法,运算,切片赋值),深拷贝和浅拷贝,列表推导式
==================================================================
技巧,subl中多行同时缩进选中按下tab
========================================================================
1.序列
(1)序列类型简介sequence
字符串 str
列表 list
元组 tuple
(2)列表的定义:
列表由一系列特定元素构成,元素之间可能没有任何关联,但是有先后顺序关系;
列表可以改变各个元素的值;
列表是一种容器;
实例:
L = [] #空列表
L = list() #空列表,变量L绑定了一个空列表
实例-创建非空列表:
L = [1,2,3,4]
L = ["beijing","shanghai","shenzhen"]
L = [1,'two',3.0,"four"]
L = [1,2,[3.1,3.2],4] #共4个元素
实例-结合len():
L = [1,2,[3.1,3.2],4]
len(L)
>>>4
(3)列表生成函数list()
list() 生成一个空列表,等同于[]
list(iterable) 用于可迭代对象初始化一个列表
实例:
L = list("hello") >>>['h', 'e', 'l', 'l', 'o']
S = "tarena"
L = list(S) >>>['t', 'a', 'r', 'e', 'n', 'a']
总结:列表与变量的区别,列表作为容器可以存放多个变量,元素,数据,与变量绑定数据相比,是可以变化的
(4)列表的运算
算数运算:
+ += * *=
+加号运算符用于拼接列表
实例1:
x = [1,2,3]
y = [4,5,6]
z = x + y #与字符串的拼接用法相同
>>>[1,2,3,4,5,6]
实例2:
[1,"range"]+['cds',3.3] >>>[1, 'range', 'cds', 3.3] #列表的拼接与数据类型没有关系,字符串的拼接仅限于字符串
+运算符用于原来列表与右侧列表拼接生成新的列表
x = [1,2,3]
y = [4,5,6]
x += y #等同于x = x + y
*运算符用于生成重复的列表
实例:
x = [1,2]*3 #x = [1,2,1,2,1,2]
*=用原列表生成重复的列表并改变变量的绑定
实例:
x = [1,2,3]
x *= 4 #x = [1,2,3,1,2,3,1,2,3,1,2,3]
(5)列表的关系(比较)运算:
>>= <<= == !=
实例:
x=[1,2,3]
y=[2,3,4]
x!=y #True 首先判断长度是否相等,再判断序列对应位置的元素是否相等
x==y #False
x>y #False 元素从左到右对应比较,只要有结果就结束比较,(猜测,比较的可能是编码值),如果前面的相同且元素结束,多出元素的为大
x<y #True
实例:
x = [1,1]
y = [1,1,-1]
x < y
>>> True
实例:
[1,'er'] < ['ere',1] #错误 无法判断
(6)列表的in/not in 运算符
x = [1,'two',3.0,"four"]
1 in x #True
"3" in x #False
3 in x #True
10 in x #False
(7)列表的基本操作:
索引index
列表[索引] 等同于字符串的索引:
正向索引:0 - len(x)-1
反向索引:-len(x) - -1
说明:注意索引和列表的区别
索引有角标,列表就是个集合
列表是可变的(目前学到的第一个元素可变集合,字符串内部内容是无法修改的),可通过索引的赋值改变列表的元素
实例:
x = [1,2,3,4]
x[2] = 3.14
print(x)
>>>[1, 2, 3.14, 4]
切片slice #回顾[:] [::]
列表切片的规则等同于字符串切片规则
实例:
x = [1,2,3,4,5]
y = [1::2] #y = [2,4]
切片赋值:
切片赋值可以改变原列表的排列,插入,删除数据;
列表中可用切片改变列表对应元素的值
实例:
L = [2,3,4]
L[0:1] = [1.1,2.2] #只切下了元素2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!记住包含前面的,不包含后面的
>>>L = [1.1,2.2,3,4] #改变了元素数量和内容
L[2:] = [3.3,4.4,5.5,6.6]
>>>L = [1.1,2.2,3.3,4.4,5.5,6.6]
L[:] = [3,4]
>>>L = [3,4]
L[1:1] = [5,6]
>>>L = [3,5,6,4] #这里没有切到任何数据,而是在6之前做插入处理
实例:
L = [1,2,3,4,5,6]
L[0::2] = [7,8,9] #将原列表中的部分数据切出来并重新赋值
>>>L = [7,2,8,4,9,6] #替换原来列表中的部分元素
L[0::2] = [7,8] #报错,这里切下了3个元素,但是赋值的时候只有2个元素
总结:
对于步长大于1的切片赋值,可能出现赋值错误问题(对应元素个数不同)
实例:
L = [1,2,3,4,5,6]
L[::2] = "ABC" #可以运行(这是一个字符串,但实际也是一个序列,和上面的列表赋值做比较)
>>>L = ['A',2,'B',4,'C',6]
L[::2] = "ABCD" #报错
总结:切片赋值是改变原列表,不会生成新列表
L = [1,2,3,4,5,6]
L2 = L
L3 = L[::2] #[1,3,5]
L[::2] = [.1,.3,.5] #L = [0.1,2,0.3,4,0.5,6] ,这个时候L2也会跟着改变,他们之间是绑定关系,L绑定(赋值)0在L2上
(8)python3中常用的序列函数
len(x) 返回序列的长度(元素的个数)
max(x) 返回序列中的最大值的元素
min(x) 返回序列中的最小值的元素
sum(x) 返回序列中所有元素的和
any(x) 真值测试,如果列表其中一个值为真值,则返回True,有一个真则为真
all(x) 真值测试,如果列表中所有值都为真值则返回True,有一个假则为假
例:L = [1,"",3.0]
print(len(L)) #3
L = [8,3,6,2]
print(max(L)) #8
print(min(L)) #2
any([0,False,None,'',[]]) #False 这里所有的元素都是假,最后一个表示空列表
any([0,False,None,'',[0]]) #True 表示不是空列表
any([0,False,None,'',[None]]) #True 表示不是空
(9)python3中列表的常用方法
见:>>>help(list)
L.index(v[,begin[,end]]) 返回对应元素的索引下标,begin为开始索引,end为结束索引
L.insert(index,obj) 将某个元素插放到列表中指定的位置
L.count(x) 返回列表中元素的个数
L.remove(x) 从列表中删除第一次出现在列表中的值
L.copy() 复制此列表(只复制一层,不进行深层复制,拷贝理论上是不会有相互影响的,因为生成了两个不想关的列表,但是这里会有部分数据存在一定的关联修改关系)
L.append(x) 在列表尾部添加单个元素
L.extend(lst) 向列表追加另一个列表
L.clear() 清空列表,等同于[:] = []
L.sort(reverse=False) 将列表的顺序按值从小到大的顺序进行排列
L.reverse() 列表反转
L.pop([index]) 删除索引对应的元素,如果不加索引,默认删除最后元素,同时返回移除元素
实例:
L = [1,2,3,4,5,3]
L.index(2) >>>1
L.index(3) >>>2
L.index(3,4) >>>5 从下标4开始找3
L.index(3,4,5) >>> 在下标4-5之间找3(实际上不包括下标5的数据)
L.insert(1,7) #在下标为1的元素之前插入7 L=[1,7,2,3,4,5,3]
L.insert(6,7) #在末尾的前面添加元素7
L.insert(1,[10,20]) #在1下标前面插入列表[10,20]
>>>L = [[10,20]1,2,3,4,5,3]
L.count(3) #对元素3进行计数统计
L.remove(3) #将第1个元素3删除
L.append(30) #在列表末尾追加元素30,与插入有相似之处。单添加可以在任何地方添加元素
L.extend([30,40,50]) #在原列表的末尾追加扩展元素,将原来的列表边长。注意与L.insert(1,[10,20])区别开来,其结果不同。
>>>L = [1,2,3,4,5,3,30,40,50]
L.clear() #将原来的列表清空
注意:
L[:] = [] 使用切片将原来的列表清空,实际只有一个列表(切片只有一个列表,在原列表上进行多种修改)
L = [] 将L原来绑定的数据列表进行释放,然后重新绑定了一个新的空列表,实际产生两个列表()
L.sort()
>>> L = [1,2,3,3,4,5] #将元素从小到大进行重新排序,排序的目的是为了便于查找某些数据(reverse=False,默认不反转,即从小到大排列升序排列)
L.sort()
总结:
L.sort() 升序排列
L.sort(reverse=False) #升序排列
L.sort(reverse=True) #降序排列
L.reverse() #反转操作 L = [3,5,4,3,2,1]
x = L.pop() #默认将最后一个值拿出并进行返回
>>>L = [1,2,3,4,5]
>>>x = 3
L.pop(1) #将下标1的元素拿出并返回
L2 = L.copy #将变量L绑定的列表进行拷贝,并绑定到L2上,L和L2的列表内容相同,单不是同一个列表,即该表其中一个列表元素,不会影响另一个列表的元素内容
总结:
拷贝也可以用切片完成:L2 = L[:],线切下一个新列表,在与标量L2进行绑定
说明:只复制一层,不进行深层复制,表示的是在嵌套列表
L1 = [20,21,22]
L2 = [10,L,30]
L3 = L1.copy()
print(L1)
print(L2)
当改变L1中的元素内容,L3会发生相应变化;
当改变L2(非L1内容,即10或者30)中的元素内容,L3会发生相应变化;(改变可以用切片和索引,例如L1(0)=50)
只对最里侧的列表内容进行同步改变
(10)复制列表深拷贝和浅拷贝列表推导式-接上
浅拷贝shallow copy:复制后的对象不完全独立
L.copy()
L[:] #切片复制是浅拷贝
实例:
L1 = [20,21,22]
L2 = [10,L1,30]
L3 = L1.copy()
L1[2] = 25 #也就是说L1变了,L2,L3会跟着变;但是L3变,L1不会跟着变
print(L2) #[10,[20,21,25],30]
print(L3) #[10,[20,21,25],30]
========================================================================
深拷贝 deep copy:将对象逐层复制(复制后的对象完全独立)
import copy #需要进行导入copy模块
实例:
import copy
L1 = [20,21,22]
L2 = [10,L,30]
L3 = copy.deepcopy(L2)
L1[2] = 25
print(L2) #[10,[20,21,25],30]
print(L3) #[10,[20,21,22],30]
(11)del运算符:用于删除列表元素
实例:
cities = ["北京","上海","深圳","天津"] #删除"深圳"元素
解:
cities.remove("深圳")
cities.pop(2)
del cities[2] #删除列表中下标为2的元素
总结:
列表是可迭代对象(目前:字符串,列表)
L = [2,3,5,7]
for x in L:
print(x) #输出列表中的数据
========================================================================
(12)列表推导式(list comrehension):用可迭代对象,依次生成列表内元素的方式
语法:
[表达式 for 变量 in 可迭代对象] #会将表达式的结果填充到列表中去
或
[表达式 for 变量 in 可迭代对象 if 条件表达式]
实例:
L=[x**2 for x in range(1,11)] #[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
L=[x**2 for x in range(1,11,2)] #[1, 9, 25, 49, 81]
L=[x**2 for x in range(1,11,) if x % 2 ==1] #[1, 9, 25, 49, 81]
(13)列表推导式的嵌套
语法:
[表达式1 for 变量1 in 可迭代对象1 (if条件表达式) 表达式2 for 变量2 in 可迭代对象2 (if 条件表达式2)]
实例:
将列表[2,3,5]中的元素与列表[7,11,13]的元素分别想乘,将得到的元素放于一个列表中
L = [x*y for x in [2,3,5] for y in [7,11,13]]
========================================================================
练习:
1.输入三个数,存于列表中,打印出这三个数最大值,最小值,平均值
pirnt("please enter three num:")
a = float(input("please enter num1:"))
b = float(input("please enter num2:"))
c = float(input("please enter num3:"))
L = [a,b,c]
print("最大值:",max(L))
print("最小值:",min(L))
print("平均值:",sum(L)/3)
补充:
L = []
L[0:0] = [a] 插入 在原始元素最前面插入一个数据
L[0:0] = [b]
L[0:0] = [c]
L[2:2] = [d] 在下标为2的元素前面插入一个元素
L[:]
print(L)
这里用切片的方式插入了一些列数据
2.输入任意整数,先判断输入的数是否为质数(只能被1和自身整除的数),如为质数则加入到列表中。再次输入任意整数,处理同上。
知道输入的数小于等于1为止。最后打印输入的质数
(知识点:输入输出,死循环,求取,for,range,列表)
我自己写的(不完整也不正确):
L=[]
x = int(input("please enter your num:"))
if x > 0:
x = int(input("please enter your num:"))
for i in range(2,x):
if x % i != 0:
L.append(x)
else:
contiune
else:
print(L)
老师写的:
primes = []
while True:
n = int(input("please enter your num(>0):"))
if n <= 1:
break
for x in range(2,n):
if n % x == 0:
break #不是素数
else:
print(n,"是素数!")
primes.append(n)
print("所有质数:",primes)
print("程序结束!")
3.生成前40个斐波那契数列,将这些书保存在列表中。最后打印这些数
解:
L=[1,1]
a=1
b=1
for i in range(1,10):
a=a+b
L.append(a)
b=b+a
L.append(b)
print(L)
4.完全数:除自身以外的所有的因数相加之和等于自身的数
例:6 , 6=1+2+3
求4个完全数并打印出来(共400多个,6,28,496,我们的电脑几乎跑不出20个)
i:完全数的个数
num:往后推导的数列
LS[]:素数的列表
LY[]:因数的列表
我自己的解法:
LS=[]
i=0
num=2
while 1:
LY=[]
if i==4:
break
for x in range(1,num):
if num % x == 0:
LY.append(x)
if sum(LY) == num:
LS.append(num)
i=i+1
num=num+1
print(LS)
总结:
1.整体思想继承了练习第2题老师写的程序:
首先设置死循环,然后在限制死循环,即先while 1(True),再break,该方法用于需要进行大量计算、但不确定终止值、确定需要数据个数的运算中。
2.程序的整体思想:
while:
if break 终止循环的条件
for 某些可迭代数据的判处理
if 主操作语句,在满足需求的情况下对数据进行一系列的输出或预输出处理:加入列表,打印,自增;可以使用if嵌套增加部分条件设置
ending
3.if else 语句应对同一变量进行判断,如果要引入其他变量,需要进行if嵌套处理
4.因数集合的清零,如果没有对因数进行清零,因数列表就会不停的追加,在进行和判断的时候将出错,因为这里的因数不仅有它自己的因数,还有前面数据的因数
干的解法:
r=[]
num = 0
while True:
num += 1
L = []
if len(r) == 4:
break
for i in range(1,num):
if num % i ==0:
L.append(i)
if sum(L) == num:
r.append(num)
print(r)
陈的解法:
n=int(input("geshu:"))
j=1
s=[]
while len(s)<=n:
l=[]
j=j+1
for i in range(1,j):
if j%i==0:
l.append(i)
if sum(l)==j:
s.append(j)
print(s)
备注:
s[] 完全数的列表集合
j 自增用于判断的原始数据
l[] 得到的因数列表集合