从零开始的Python ACM Ch.1:数据类型及基本数据处理
基本数据类型
可迭代数据类型
通用操作:
- 遍历
- max
- min
- sum
- len
- 成员测试 in、not in
序列数据类型
通用操作:
- 索引
- 切片
- index
- count
- 同类型加法拼接
- 整数乘法重复
字符串
不可变数据类型(对字符串的所有修改操作,都是返回一个新的字符串)
特有操作:
s.upper()
s.lower()
s.replace(sub1, sub2)
s.join(Iterable[str])
s.format()
s.split(c)
元组
不可变数据类型,基本是拿来用索引,或者切片
列表
可变数据类型
特有操作:
通过索引进行修改
通过切片进行修改
ls.append(x)
del ls[i] i为元素索引
ls.remove(x)
x为元素值ls.extend(lt2)
ls.insert(i, x)
ls.reverse()
ls.clear()
列表表达式
集合 & 字典
集合中的元素、字典的键 都必须为不可变数据类型,不能重复
如果直接对字典进行for
循环的遍历,那么出来的是字典的键
集合的特有方法:
s.pop()
弹出集合s中的一个元素s.add(x)
将x添加到集合s中s.remove(x)
删除集合s中的元素x,x不存在则出错s.discard(x)
删除集合s中的元素x,x不存在不出错s.update(t)
将集合t合并到集合s中s.clear()
清空集合ss-t
差集s&t
交集s|t
并集s^t
并集减去交集s.isdisjoint(t)
判断是否相交 比较操作 判断包含关系
字典的特有方法:
通过键进行索引
d.keys()
所有键的迭代器d.values()
所有值的迭代器d.items()
所有键值对的迭代器d.get(key, default)
如果key存在,返回d[key],否则返回defaultd.pop(key, default)
返回d.get(key, default)
并不出错的删除keyd.popitem()
d.update(d2)
列表表达式
一般我们使用的列表长这样
1 | ls = [123,456,789,0] |
但是Python里面有个东西叫做列表表达式,例如
1 | ls1 = [i for i in range(0,100)] |
这会生成一个带有0-99的int
数据类型的列表,非常简洁
列表的排序
一般来说,你自己在Python里面写的对列表进行排序的函数,都不如内置的list().sort(*, key=key, reverse=False)
要快,谁让人家是C语言写的排序呢……
但是list().sort()
有个坑,我前两天帮人数学建模的时候还是踩进了这个坑,就是:这个方法是直接作用于列表本身,没有返回值的,所以进行赋值的时候就会变成none
例题1
下面的列表a
是人物的名字,b
是他们对应的年龄,请输出18岁以下的人物并根据他们的年龄进行升序排列
1 | a = ['tom', 'iron man','jerry', 'donald', 'micky', 'spider man'] |
我的做法是用多一个列表,往里面用元组的形式填他们的名字以及年龄信息
1 | ls = [] |
对ls
进行打印,得出这样的一个列表
1 | [('tom', 3), ('jerry', 1), ('donald', 8), ('micky', 2)] |
再通过sort
函数和lambda
表达式进行排序,对所需要的东西进行打印
1 | ls.sort(key=lambda x: x[1]) |
输出为
1 | jerry |
但是经过教员的提醒,还有个zip()
函数可以直接把两个列表中的对应位置的元素合在一起变成元组
1 | items = list(zip(a,b)) |
这样做的结果跟上面的ls
的结果是一样的
然后再在列表表达式里面筛选,两步可以合在一起
1 | items = [item for item in list(zip(a,b)) if item[1] < 18] |
启示:少用字典,筛选放在后面去
例题2
2089. 找出数组排序后的目标下标 - 力扣(LeetCode)
我的题解:
1 | class Solution: |
优化版(因为找到了以后,再往后就不存在要找的了,所以可以直接break
掉)
1 | class Solution: |
例题3
我的题解:
1 | class Solution: |
优化版(找不同的可以用集合去做):
1 | class Solution: |
例题4
599. 两个列表的最小索引总和 - 力扣(LeetCode)
我的题解:
1 | class Solution: |
enumerate(list)
在遍历的过程中出现index, value
的返回值,可以在for循环使用,例如
1 | ...(上面已经定义了ls为列表) |
所以上面这一题也可以改一改,用这个方法可以免去用ls.index()
的麻烦
例题5
2200. 找出数组中的所有 K 近邻下标 - 力扣(LeetCode)
我的题解(OT
了):
1 | class Solution: |
优化版:
思路是从i
所在位置往左往右k
个位置是否有key,如果有的话就进行计算,没有就跳过,省去了很多遍历
1 | class Solution: |
列表的空间
列表在内存中是连续的,但是如果要用申请的空间之外的地方的话(即加长列表)就要再次申请,会减慢运行,所以可以先申请一大片空间
1 | ls = [0]*1000 |