1.7 序列结构
可变对象和与可变对象
Python中内置数据类型主要有三大类:
-
数字:整型、浮点型
-
序列:字符串、列表、元组、集合
-
映射:字典
按照是否可以原地修改分为两大类:
-
不可变对象(数字,字符串,元组,不可变集合)
不可变的分类中没有哪个对象类型支持原地修改,但可以创建新的对象并将结果赋予变量
-
可变对象(列表,字典,可变集合)
相反,可变的类型总是可以通过相关的操作进行原处修改,而不需要创建新的数据对象
序列的通用操作
索引,切片,相加,相乘,迭代和成员资格检查
索引操作
索引中的所有元素都有编号(角标),角标从0开始计数,当然在Python当中,也可以使用负角标来访问元素,所有最后一个元素的角标-1(倒数第一个)
>>> word = "hello"
>>> word[0]
'h'
>>> word[2]
'l'
>>> word[-1]
'o'
>>> word[-5]
'h'
>>> word[10]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
对于序列的字面量,可以直接用角标操作,而不需要变量
>>> "hello"[3]
'l'
>>> "hello"[-1]
'o'
切片操作
索引是一次去一个数据,切片是一次取一片数据,要定开始和结尾,包括步长(默认为1)
>>> word = "12345678"
>>> word[0:3]
'123'
>>> word[-3:-1]
'67'
不管是正索引,还是负索引,必须要保证顺序
>>> word[1:8:2]
'2468'
>>> word[-6:-2:3]
'36'
>>> word[7:1:-2]
'864'
>>> word[-1:-5:-1]
'8765'
>>> word[-1:-5:1]
''
>>> word[:]
'12345678'
>>> word[2:]
'345678'
>>> word[:5]
'12345'
>>> word[-5:]
'45678'
>>> word[-3::-1]
'654321'
步长是正数,开始~结尾 递增
步长是负数,开始~结尾 递减
>>> text = "我爱你"
>>> text = text[::-1]
>>> text
'你爱我'
>>> text = text[-1:-4:-1]
>>> text
'我爱你'
相加操作
指的是两个序列合并,会产生新的序列对象,不会改变原先序列的值
>>> s1 = "abc"
>>> s2 = "ABC"
>>> s1 + s2
'abcABC'
>>> s1
'abc'
>>> s2
'ABC'
相加只能是在同类型序列之间进行
相乘操作
将序列与数字x相乘,将重复这个序列x次创建一个新的序列
>>> s1
'abc'
>>> s3 = s1 * 3
>>> s3
'abcabcabc'
迭代操作
可以在for循环中迭代序列中的每一元素,或者迭代角标来获取元素
>>> s1
'abc'
>>> for i in s1:
... print(i)
...
a
b
c
>>> for i in range(len(s1)):
... print(s1[i])
...
a
b
c
>>> word[0] = '9'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
成员资格检查操作
就是验证一个数据元素是否存在于当前序列当中
>>> '8' in word
True
>>> 8 in word
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'in <string>' requires string as left operand, not int
>>> '10' not in word
True
>>> '10' in word
False
>>> 5 in range(0,10)
字符串
不可变对象,一个有序的字符集合,用于存储和表现基本文本信息
字符串不允许原地修改值,字符串的长度大小一旦定义则不能修改
如果真想去修改字符串的话,只能创建一个该字符串的副本,副本的内容就是修改过后的内容
测试字符串方法:
-
isalnum():验证是否只包含数字和字母
-
isalpha():验证是否只包含字母
-
isdigit():验证是否只包含数字
-
isidentifier():验证是否是合法的标识符
-
islower():验证内容当中字母是否全小写
-
isupper():验证内容当中字母是否全大写
-
isspace():验证是否只包含空格
搜索字符串方法:
-
endswith(str):验证是否已str后缀结尾
-
startswith(str):验证是否已str前缀开始
-
find(str):返回str从左到右第一次出现的角标,如果不存在返回-1。rfind()相反
-
index(str):功能和find一样,如果不存在则有异常
-
count(str):记录str出现的次数,不带覆盖
转换字符串:
-
capitalize():将字符串复制并大写第一个字母
-
lower():将所有字母转小写
-
upper():将所有字母转大写
-
title():将字符串复制并将每个单词的首字母大写
-
swapcase():将字符串复制,将小写转大写,将大写转小写
-
replace(a,b):将原先字符串中a替换为b,产生新字符串
-
split(str):将str为分隔符,将字符串分割,结果是一个字符列表
-
partition(str):以str为中心部分,将字符串分为左右两部分
删除字符串空格:
-
lstrip():删除字符串左边的空格
-
rstrip()
-
strip()
格式化字符串:
-
center(w):以w为宽度,让内容居中显示
-
ljust()
-
rjust()
>>> "123abc".isalnum()
True
>>> "我爱你123abc*!&@%#^&%&".isalnum()
False
>>> "abc".isalpha()
True
>>> "123".isalpha()
False
>>> "123abc".isalpha()
False
>>> "123".isdigit()
True
>>> "abc".isdigit()
False
>>> "sum".isidentifier()
True
>>> "123abc".isidentifier()
False
>>> "abc".islower()
True
>>> "ABC".islower()
False
>>> "123abc".islowe()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'islowe'
>>> "123abc".islower()
True
>>> " ".isspace()
True
>>> " ad asd asd".isspace()
False
>>> "123,456,789".find("456")
4
>>> "123,456,789".rfind("456")
4
>>> word = "123456789456"
>>> word.find("456")
3
>>> word.rfind("456")
9
>>> word
'123456789456'
>>> word.index("123")
0
>>> word.index("456")
3
>>> word.find("666")
-1
>>> word.index("666")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
>>> "121212121".count("121")
2
>>> name = "anglababy"
>>> name.capitalize()
'Anglababy'
>>> name
'anglababy'
>>> "Andy Mimi Lala".lower()
'andy mimi lala'
>>> "Andy Mimi Lala".lower().upper()
'ANDY MIMI LALA'
>>> "mynameishaha".title()
'Mynameishaha'
>>> "my name is haha".title()
'My Name Is Haha'
>>> s= "my name is haha".title()
>>> s
'My Name Is Haha'
>>> s.swpacase()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'swpacase'
>>> s.swapcase()
'mY nAME iS hAHA'
>>> s = "宇智波萨斯尅,宇智波马达啦,宇智波一大气,宇智波欧鼻头"
>>> s.replace("宇智波","千手")
'千手萨斯尅,千手马达啦,千手一大气,千手欧鼻头'
>>> s
'宇智波萨斯尅,宇智波马达啦,宇智波一大气,宇智波欧鼻头'
>>> s.split(",")
['宇智波萨斯尅', '宇智波马达啦', '宇智波一大气', '宇智波欧鼻头']
>>> l = s.split(",")
>>> l[1]
'宇智波马达啦'
>>> "莫西莫西海雅库摩多摩多".partition("雅")
('莫西莫西海', '雅', '库摩多摩多')
>>> "123456789".partition("456")
('123', '456', '789')
>>> " 123".lstrip()
'123'
>>> "123 ".rsrtip()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'rsrtip'
>>> "123 ".rstrip()
'123'
>>> " 8798 ".strip()
'8798'
>>> "I Love You".center(16)
' I Love You '
>>> s = "abc"
>>> s.center(10)
' abc '
>>> s.ljust(10)
'abc '
>>> s.rjust(10)
' abc'
列表
列表是Python中最具有灵活性的有序集合对象类型,与字符串不同的是,列表可以包含任何种类的对象:数字、字符串、甚至是列表。同样,与字符串不同的是,列表是可变对象,他们都支持在原处修改的操作,同样列表的长度是可变的。
可变:列表空间中,所存储并指向某个数据对象的地址是可变的
列表的创建方式
直接指定元素
>>> [1,2,3,4,5]
>>> l = [1,2,3,4,5]
指定长度但不指定元素,相当于创建一个长度为n但不存任何数据对象地址的空列表
>>> l = [None] * 10
>>> l
[None, None, None, None, None, None, None, None, None, None]
通过list函数将其他的数据转换为列表,这些数据必须是可迭代的,可迭代的就是可以被for循环操作
>>> list() # 得到一个长度为0的列表
[]
>>> l = list("abcd")
>>> l
['a', 'b', 'c', 'd']
>>> l[0]
'a'
>>> l[-1]
'd'
>>> l = list(range(0,5))
>>> l
[0, 1, 2, 3, 4]
>>> l =list(1234)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
列表的特有操作
-
修改元素
>>> l [0, 1, 2, 3, 4] >>> l[0]=5 >>> l [5, 1, 2, 3, 4]
-
切片修改
>>> l = [1,2,3,4,5,6,7,8,9] >>> l [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l[3:7] = [666,888,999] >>> l [1, 2, 3, 666, 888, 999, 8, 9]
-
删除操作
>>> l [1, 2, 3, 666, 888, 999, 8, 9] >>> del l[3] >>> l [1, 2, 3, 888, 999, 8, 9] >>> del l[-3] >>> l [1, 2, 3, 888, 8, 9] >>> del l # 删除列表对象 连着变量也一同删除 >>> l Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'l' is not defined
列表的内置函数
-
append():在列表的表尾添加一个元素对象
>>> l = [1,2,3] >>> l.append(4) >>> l [1, 2, 3, 4] >>> l1 = [1,2,3,4] >>> l2 = [5,6,7,8] >>> l1.append(l2) >>> l1 [1, 2, 3, 4, [5, 6, 7, 8]] >>> l1.append("abc") >>> l1 [1, 2, 3, 4, [5, 6, 7, 8], 'abc']
-
clear():清空列表,不代表删除列表对象
>>> l.clear() >>> l []
-
copy():复制一份新的列表对象,与原列表内容一致,将新列表的地址返回
>>> l1 = [1,2,3,4] >>> l2 = l1 >>> l2[0] = 5 >>> l1 [5, 2, 3, 4] >>> l2 = l1.copy() >>> l1 [5, 2, 3, 4] >>> l2 [5, 2, 3, 4] >>> l2[0]=10 >>> l1 [5, 2, 3, 4] >>> l2 [10, 2, 3, 4]
-
count():计算某个元素在列表出现的次数
>>> l = [1,1,2,3,1,2,3,4,3,2,1,1,2] >>> l.count(2) 4
-
extend():将其他列表的内容扩展到当前列表中(将后者内部所有的元素依次添加在当前列表中)
>>> l1 = [1,2,3,4] >>> l2 = [5,6,7,8] >>> l1.extend(l2) >>> l1 [1, 2, 3, 4, 5, 6, 7, 8] >>> l2 [5, 6, 7, 8] >>> l1.extend("abc") >>> l1 [1, 2, 3, 4, 5, 6, 7, 8, 'a', 'b', 'c'] >>> l1.extend(123) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not iterable #如何理解extend? lst = [] def extend(lter): for i in Iter: lst.append(i)
不同于两个序列相加,两个序列相加,是直接创建新的序列对象的
-
index():从左到右返回元素的角标,如果不存在则抛出异常
>>> l = [1,2,3,4] >>> l.index(3) 2 >>> l.index(5) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 5 is not in list >>> l.find(3) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'list' object has no attribute 'find'
-
insert():在某个位置插入元素,角标如果越界,如果是负数,则为倒数第几个;如果角标大于列表长度,在末尾添加
>>> l [1, 2, 3, 4] >>> l.insert(2,5) >>> l [1, 2, 5, 3, 4] >>> l.insert(10,6) >>> l [1, 2, 5, 3, 4, 6] >>> l.insert(-2,7) >>> l [1, 2, 5, 3, 7, 4, 6]
-
pop():在列表的尾部删除一个元素,弹栈;append理解为进栈
>>> l = [1,2,3,4] >>> l.append(5) >>> l [1, 2, 3, 4, 5] >>> l.pop() 5 >>> l [1, 2, 3, 4]
-
remove():删除从左到右第一个指定的元素
>>> l [1, 2, 3, 4] >>> l.remove(4) >>> l [1, 2, 3] >>> l.remove(2) >>> l [1, 3] >>> l = [1,1,1,2,2,3,3] >>> l.remove(1) >>> l [1, 1, 2, 2, 3, 3]
-
reverse():反转列表
>>> l.reverse() >>> l [3, 3, 2, 2, 1, 1]
-
sort():排序
>>> l = [3,2,9,1,6,5,7,4,8] >>> l.sort() >>> l [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l.reverse() >>> l [9, 8, 7, 6, 5, 4, 3, 2, 1]
列表解析式
是通过for循环语句来创建列表
>>> l1 = [1,2,3,4,5,6,7,8,9,10]
>>> l1 = list(range(1,11))
>>> l1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> l1 = [x for x in range(1,11)]
>>> l1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> l1 = [x for x in range(1,21) if x%3==0 ]
>>> l1
[3, 6, 9, 12, 15, 18]
>>> l2 = [x/2 for x in l1]
>>> l2
[1.5, 3.0, 4.5, 6.0, 7.5, 9.0]
二分查找算法
前提是我们的序列必须有序的(递增,递减)
# 二分查找
def binarySearch(lst, key):
min_index = 0
max_index = len(lst) - 1
mid_index = (min_index + max_index) // 2
while lst[mid_index] != key:
if lst[mid_index] < key:
min_index = mid_index + 1
elif lst[mid_index] > key:
max_index = mid_index - 1
if min_index > max_index:
return -1
mid_index = (min_index + max_index) // 2
return mid_index
lst = [x for x in range(1,13)]
print(binarySearch(lst,9))
print(binarySearch(lst,1))
print(binarySearch(lst,8.5))
print(binarySearch(lst,15))
lst = [x ** 2 for x in range(1,13)]
print(binarySearch(lst,121))
print(binarySearch(lst,120))
选择排序算法
def selectionSort(lst):
for i in range(len(lst) - 1):
for j in range(i+1,len(lst)):
if lst[i] > lst[j]:
lst[i],lst[j] = lst[j],lst[i]
"""
temp = lst[i]
lst[i] = lst[j]
lst[j] = temp
"""
lst = [5,1,9,8,2,6,7,4,3]
selectionSort(lst)
print(lst)
冒泡排序算法
def bubbleSort(lst):
for i in range(len(lst) - 1):
for j in range(len(lst) - 1 - i):
if lst[j] > lst[j + 1]:
lst[j], lst[j + 1] = lst[j + 1], lst[j]
lst = [5,1,9,8,2,6,7,4,3]
bubbleSort(lst)
print(lst)
插入排序算法
def insertionSort(lst):
for i in range(1,len(lst)):
e = lst[i]
j = i
while j > 0 and lst[j - 1] > e:
lst[j] = lst[j - 1]
j -= 1
lst[j] = e
lst = [5,1,9,8,2,6,7,4,3]
insertionSort(lst)
print(lst)
计数排序算法
def countingSort(lst):
minVal = min(lst)
maxVal = max(lst)
temp = [0] * (maxVal - minVal + 1)
offset = minVal
for number in lst:
temp[number - offset] += 1
i = 0
for index in range(len(temp)):
for k in range(temp[index]):
lst[i] = index + offset
i += 1
lst = [5,1,9,8,2,6,7,4,3]
countingSort(lst)
print(lst)
基数排序算法
import random
def getIndex(num,r):
if len(str(num)) < r:
return 0
return int(str(num)[-r])
def radixSort(lst):
maxVal = max(lst)
radix = len(str(maxVal))
temp = [None] * 10
for i in range(10):
temp[i] = []
# 1个位 2十位 3百位
for r in range(1,radix + 1):
for num in lst:
temp[getIndex(num,r)].append(num)
i = 0
for k in range(len(temp)):
if len(temp[k]) != 0:
for j in range(len(temp[k])):
lst[i] = temp[k][j]
i += 1
temp[k].clear()
lst = []
for i in range(20):
lst.append(random.randint(1,300))
radixSort(lst)
print(lst)
元组
和列表一样是序列的一种,是用圆括号括起来的()
元组是一种不可变序列,可以理解为不可变的列表
除了内部元素不能修改(增,删,改)之外,其他的和列表用法差不多
>>> t = ()
>>> type(t)
<class 'tuple'>
>>> t = (1)
>>> type(t)
<class 'int'>
>>> t = (1,)
>>> type(t)
<class 'tuple'>
>>> t = (1,2,3)
>>> type(t)
<class 'tuple'>
>>> t = 1,2,3,4,5
>>> type(t)
<class 'tuple'>
>>> t = "你好","世界","哈哈"
>>> type(t)
<class 'tuple'>
>>> l = [1,2,3,4,5]
>>> type(l)
<class 'list'>
>>> t = tuple(l)
>>> t
(1, 2, 3, 4, 5)
>>> t = tuple("abcde")
>>> t
('a', 'b', 'c', 'd', 'e')
元素与列表相同的操作
-
count()、index()
-
len()、max()、min()、tuple()
>>> t = (1,2,3,4,5)
>>> max(t)
5
>>> min(t)
1
>>> len(t)
5
>>> t.count(5)
1
>>> t.index(3)
2
>>> t.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'sort'
>>> t.find(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'find'
元组中不允许的操作
-
修改、新增元素
-
删除某个元素(但是可以删除整个元组)
-
所有会对元组内部元素发生修改动作的方法
>>> t.append(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
>>> t.remove(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'remove'
>>> t
(1, 2, 3, 4, 5)
>>> t[0] = 666
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> del t[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object doesn't support item deletion
>>> del t
>>> t
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 't' is not defined
元组只保证它的一级子元素不可变,对于嵌套的元素内部,不保证不可变的
说白了指的就是元组所存储的对象地址不可变
>>> t = (1,2,[3,4])
>>> t[0] = 666
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t[2] = [5,6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t[2][0] = 5
>>> t[2][1] = 6
>>> t
(1, 2, [5, 6])
>>> id(t[2])
53493544
>>> t[2].append(7)
>>> t
(1, 2, [5, 6, 7])
>>> id(t[2])
53493544
所以,在使用元组时,尽量使用数字、字符串和元组这种不可变对象的数据类型作为元素
一般什么时候去使用?当数据一旦确定下来,不可更改时,则使用
>>> address = ("172.16.20.222","8080") # IP地址与端口号绑定