Week 2
本周学习主要内容包括列表,元组,字符串,字节序列
三元表达式:
- 是一个非常简单的表达式
- 表达式在python中一般只能写成一行
- 三目运算符
#真值执行的表达式为if,假值执行的表达式为else
a = input()
a = int(a)
print('>5') if a>5 else print('<=5')
数据结构
- 内建数据结构:序列sequence(字符串str;字节序列bytes,bytearray;列表list,元组tuple)、键值对(集合set;字典dict)
- 线性数据结构:线性表、顺序表、链接表
列表(list):
- 一个排列整齐的队伍,Python采用顺序表实现
- 列表内的个体为元素,若干元素组成列表
- 元素可以是任意对象(数字、字符串、对象、列表等)
- 列表内元素有顺序,可以使用索引
- 线性的数据结构
- 使用 [ ] 表示
- 列表是可变的
初始化:
- list() --> new empty list
- list(iterable) --> new list initialized from iterable’s items
- [ ]
- 列表不能一开始就定义大小
索引:
- 也叫“下标”
- 正索引:从左至右,从0开始,为列表中每一个元素编号。
如果列表有元素,索引范围为[0,长度-1]
- 负索引:从右至左,从-1开始
如果列表有元素,索引范围为[-长度,-1]
- 正负索引均不可超界,负责引发异常indexError
- 可以认为左边为头部,右边为尾部,左边下界,右边上界
- 列表通过索引访问,list[index],index就是索引,使用中括号[ ]访问
- 使用索引定位访问元素的时间复杂度为O(1),是最快的方式,使用列表最好的方式
查询:
- index(value,[start,[stop]]):
通过值value,从指定区间查找列表内的元素是否匹配
匹配第一个就立即返回索引
匹配不到抛出异常ValueError
- count(value):
返回列表中匹配value的次数
- 时间复杂度:
index和count方法都是O(n)
随着列表数据规模的增大效率下降
- 如何返回列表元素个数?如何遍历?如何设计才能高效?
len()
修改:
- 先索引,后修改(直接使用 list[n] = x 赋值修改)。注意索引不能超界
增加单个元素:
- append(object0 --> None:
列表尾部追加元素返回None
返回None意味着没有新列表产生,就地修改
定位时间复杂度是O(1)
- insert(index,object) --> None:
在指定的索引index处插入元素object
返回None就意味着没有新列表产生,就地修改
定位时间复杂度是O(n)
- 超界问题?
超越上界,尾部追加
超越下界,头部追加
增加多个元素:
- extend(iterable) --> None:
将可迭代对象的元素追加进来,返回None
就地修改,本列表自身扩展
- “+” --> list:
连接操作,将两个列表连接起来,产生新列表,原列表不变
本质上调用的是魔术方法__add__()方法
- “*” --> list:
重复操作,将本列表重复n次,返回新列表
删除:
- remove(value) --> None:
从左至右查找第一个匹配value的值,找到就移除该元素,并返回None,否则ValueErr(
- pop([index]) --> item:
不指定索引index,就从列表尾部弹出一个元素
指定索引index,就从索引处弹出一个元素,索引超界抛IndexError
指定索引时间复杂度O(1)
- clear() --> None:
清除列表所有元素,剩下一个空列表
反转:(最好不用)
- reverse() --> None:
将列表反转,返回None
就地修改
排序:
- sort(key = None, reverse = False) --> None:
对列表元素进行排序,就地修改,默认升序
reverse为True,反转,降序
key一个函数,指定key如何排序,lst.sort(key=function)
列表复制:
- list.copy()
- shadow copy:
影子拷贝,也叫浅拷贝,遇到引用类型数据,仅仅复制一个引用而已
- deep copy:
深拷贝,往往会递归复制一定深度
- 大多数语言提供的默认复制行为都是浅拷贝
元组(Tuple)
- 一个有序的元素组成的集合
- 使用小括号 ( ) 表示
- 元组是==不可变==对象
初始化:
- tuple() --> empty tuple
- tuple(iterable) --> tuple initialized from iterable’s items
索引:
同列表规则一样,不可超界
查询:
同列表方法一样,时间复杂度一样。index、count、len等
增删改:
- 元组元素的个数在初始化的时候就定义好了,所以不能为元组增加元素、删除元素或修改元素内容
排序方法:
- if分支
- max函数
- 列表sort方法
- 冒泡排序
- 选择排序(之后讲)
冒泡排序(Bubble Sort):
nums = [9,8,7,6,5,4,3,2,1]
length = len(nums)
print(nums)
print('~~~~~~~~~')
#该算法能提前结束吗
count = 0
swap_count = 0
for i in range(length-1):
flag = False #假设这一趟没有交换过
for j in range(length-1-i):
count += 1
if nums[j] > nums[j+1]:
temp = nums[j]
nums[j] = nums[j+1]
nums[j+1] = temp
swap_count += 1
flag = True #说明交换过
print(nums) #每一趟走完的当前情况
if not flag:
break
print('---------')
print(nums) #最终结果
print(count,swap_count)
字符串
- 在内存中一个挨一个有序的字符序列
- 不可变!!!字面常量
切割:
- split
- rsplit
- splitlines
- partition
- rpartition
替换:
.replace — 原字符串没变,生成一个新字符串,python中字符串替换不是就地修改。不支持模式匹配,以后使用re正则表达式完成。
指针只遍历一遍,不回头
移除:
- strip(chars)
- lstrip
- rstrip
括号内叫chars(字符集)而非substring(子串),通用chars=none;
默认行为:将两头的空白字符都拿掉;
有指定时只移除两端的指定字符,一直移除到遇到不属于字符集的字符为止
首位判断:
- starswith()
- endswith()
效率较高,因为只从0或-1索引开始比对,精确匹配,要求子串字符与原字符串完全一致,返回布尔值
其他函数:
- upper() / lower(): 与前面返回形式有关,比如a.split().upper() 不可以,因为split返回列表;而a.split(’,’).pop().upper()可以返回,又叫链式编程
- .isspace():可以用来判断空白字符
- .isnumeric() / .isdigit() / .isdecimal():只认0-9,小数点不行
- .isalpha():只认英文大小写字母
……………………………………
C风格printf-style:
- 占位符:% 【%d、%s、%f……】
- 修饰符:占位符之间可以加修饰符 【%03d】
- format%values:values可以用元组,依次对应;或字典,无关顺序;python 3.6之后可以用f前缀字符串/插值字符串或format函数
format函数:
"{} {} {} {a} {b}".format(1,2,3,a=100,b=200)
#1,2,3按位置传参;a=100按名称传参 (1,2,3) {'a':100; 'b':200}
- 时间(格式化)
import datetime
d1 = datetime.datetime.now
"{:%Y %y %m %d %H %M %S}".format(d1)
#2020 20 3 28 12 12 54
"{:%Y/%m/%d %H:%M:%S}".format(d1)
#2020/3/28 12:12:54
- 进制:
"{0:b} {0:x} {0:X} {0:o}".format(31)
"{0:#b} {0:#x} {0:#X} {0:#o}".format(31)
- 浮点数:
带f保留浮点数
"{:<5.1f}".format(3**0.5)
#:5代表字符宽度为5,所以有两个空白字符占位
#<左对齐 所以后面空位
#>为右对齐
#^居中对齐,两边加#
#.1 小数点后保留一位,默认f为小数点后保留六位
#宽度可以被撑破 要注意
字符序列
解码与编码:
- .encode() / .decode()
- 编码过程与解码过程要对应(默认utf-8编码)
- python 3中字符串使用的是unicode
- b开头的字符串为bytes类型
ASCII:(美国信息交换标准代码-阿斯克码)
- 总共128种变化!!0-127!!(十六进制)
- 在内存中数据都是0和1构成,无差别;当指定某些字节,为他赋予数据类型时,这些数值才有了不同的理解。
- 阿斯克码表需要熟记背过!!
- 特殊:
- '0x00’是null字符,长度为一;
- ''是空串,长度为零;
- 回车换行符 ‘\x0d0a’ \r=\x0d(回车符) \n=\x0a(换行符);
- 空格符 ‘\x20’
- \x31 49 是字符1; \x41 65 是字符A;\x61 97 是字符a
- 1字节256种状态;2字节65536状态
- UTF-8 和 GBK都兼容了ASCII
bytes(不可变字节序列):
- #bytes(iterable_of_ints) -> bytes 单字节整数可迭代对象,不能超过255
bytearray(可变字节数组):
- bytearray没有简写方式,只能bytearray(),可以看做包装
- bytearray是可变的,数组,list,既像列表又像字符串
- 相对用的较少
- bytearray是就地修改
字节序:
- 内存中对于超过一个字节数据的分布方式
- 大尾/大端模式: ‘abcd’ => 0123
字符串:头=> 尾 存放地址:低=> 高 - 字符串采用了大端模式(Big endian),尾巴字符往高地址放
- 小尾/小端模式:与上相反
- int类型,C语言:
1字节整型,无所谓大小端
2字节整型(0x12 34 56), #有大小端区分 - 大多数语言 使用大端模式
线性结构特征:
- 可迭代(for,in……)
- 有长度(length……)
- 可索引(a[0]……)
定义:
- x[start:stop:步长]是切片,x[index] 对索引范围的描述叫切片
- start是0可不写,stop到末尾可不写 ([:]表示从头到尾)
- 切片结果是本类型
- x[1:] #掐头
- x[0:-1] #去尾
- x[1:-1] #掐头去尾
- x[-1000::1], x[-100:] #超界不报错,但有方向
本质:
切片是浅拷贝,创建副本
切片赋值:
只能赋值可迭代对象,方便使用但并不好,因为会引起数值变动或数据挪动,对于顺序表将降低效率