697 lines
16 KiB
Markdown
697 lines
16 KiB
Markdown
# Python
|
||
## 变量
|
||
在python中,可以通过如下方式创建变量:
|
||
```python
|
||
message = "Hello Python Crash Course world!"
|
||
```
|
||
## 字符串
|
||
### 字符串首字母大写
|
||
```python
|
||
name = "ada lovelace"
|
||
print(name.title())
|
||
```
|
||
### 字符串全部字符大写
|
||
```python
|
||
name = "Ada Lovelace"
|
||
print(name.upper())
|
||
```
|
||
### 字符串全部字符小写
|
||
```python
|
||
name = "Ada Lovelace"
|
||
print(name.lower())
|
||
```
|
||
### 字符串删除空白符
|
||
```py
|
||
name = " Asahi Ogura `
|
||
# 删除左空白
|
||
name.lstrip()
|
||
# 删除右空白
|
||
name.rstrip()
|
||
# 删除左右空白
|
||
name.strip()
|
||
```
|
||
### 访问字符串中字符
|
||
ptyhon可以通过数组下标来访问字符串中的字符,如果字符串长度为n,那么索引范围为`[0, n-1]`,同时,在python中还可以使用负数的索引,索引范围为`[-n, -1]`。
|
||
|
||
在python字符串中,第一个字符可以通过索引下标`0`和`-n`来访问,最后一个字符可以通过`n-1`和`-1`来访问。
|
||
|
||
### 字符串切片
|
||
字符串切片可以通过`str[from:to:step]`来标识,其标识下标为`[from, to)`范围内的子字符串,步长为`step`。
|
||
|
||
```py
|
||
temp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||
```
|
||
|
||
其中,输出`[0,10)`范围内的字符串可以采用如下方式:
|
||
```py
|
||
print(temp[0:10]) # ABCDEFGHIJ
|
||
print(temp[0:10:1]) # ABCDEFGHIJ
|
||
```
|
||
|
||
当步长被设置为2时,输出内容如下:
|
||
```py
|
||
print(temp[0:10:2]) # ACEGI
|
||
```
|
||
|
||
正数索引和负数索引混用:
|
||
```py
|
||
# 输出不包含末尾2个字符的子字符串
|
||
print(temp[0:-2]) # ABCDEFGHIJKLMNOPQRSTUVWX
|
||
print(temp[0:24]) # ABCDEFGHIJKLMNOPQRSTUVWX
|
||
print(temp[:-2]) # ABCDEFGHIJKLMNOPQRSTUVWX
|
||
|
||
# 输出末尾两个字符的子字符串
|
||
print(temp[-2:])
|
||
```
|
||
逆序输出字字符串
|
||
```py
|
||
print(temp[::-1]) # ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||
print(temp[-1:0:-1]) # ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||
print(temp[25:0:-1]) # ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||
```
|
||
### 字符串迭代
|
||
python中字符串可迭代,示例如下:
|
||
```py
|
||
temp = "ABCDE"
|
||
for ind, ch in enumerate(temp):
|
||
print("ind = "+str(ind)+", ch = "+ch, end="\n")
|
||
|
||
# ind = 0, ch = A
|
||
# ind = 1, ch = B
|
||
# ind = 2, ch = C
|
||
# ind = 3, ch = D
|
||
# ind = 4, ch = E
|
||
```
|
||
|
||
## 数字
|
||
### /
|
||
python中,整数执行`/`操作默认并不会进行整除,而是可能生成浮点数
|
||
```py
|
||
print(3/2) # 1.5
|
||
```
|
||
|
||
### //
|
||
python中,如果要执行整除,应该使用`//`运算符,该运算符为向下取整
|
||
```py
|
||
print(3//2) # 1
|
||
print(-3//2) # -2
|
||
```
|
||
> 和java不同,java在执行整数除时,会舍弃掉小数部分,例如`-3/2`,java中结果为-1,而python则是向下取整为-2
|
||
>
|
||
> 如果python中`/`操作想要和java保持一直,可以使用math中的`trunc`函数,`math.trunc(-3/2)`返回结果和java中一样,为`-1`
|
||
|
||
### 数字类型向字符串类型转换
|
||
可以通过str函数将数字类型转化为字符串类型
|
||
```py
|
||
temp = 1.2
|
||
print("temp = "+str(temp))
|
||
```
|
||
|
||
## 列表
|
||
python中通过`[e1, e2, ...]`的形式来标识列表
|
||
|
||
### 访问列表中元素
|
||
可以通过数组下标的方式来访问列表中的元素
|
||
```py
|
||
temp = [1, "2", "san"]
|
||
|
||
print(temp[1]) # 2
|
||
print(temp[-2]) # 2
|
||
```
|
||
|
||
### 列表元素操作
|
||
#### 修改
|
||
```py
|
||
temp = [1, "2", "san"]
|
||
|
||
temp[2] = 3.0
|
||
print(temp) # [1, '2', 3.0]
|
||
```
|
||
|
||
#### 插入到末尾
|
||
如果想要向数组末尾插入元素,可以调用append方法
|
||
```py
|
||
temp = [1, "2", "san"]
|
||
|
||
temp.append("four")
|
||
print(temp) # [1, '2', 'san', 'four']
|
||
```
|
||
#### 在某位置之前插入
|
||
如果想要在特定位置之前插入元素,可以调用insert方法
|
||
```py
|
||
temp = [1, "2", "san"]
|
||
|
||
temp.insert(1, "1.5")
|
||
print(temp) # [1, '1.5', '2', 'san']
|
||
temp.insert(4, "four")
|
||
print(temp) # [1, '1.5', '2', 'san', 'four']
|
||
```
|
||
#### 删除列表中的元素
|
||
如果想要删除列表中的元素,可以通过del关键字进行删除
|
||
```py
|
||
temp = [1, "2", "san"]
|
||
|
||
del temp[1]
|
||
print(temp) # [1, 'san']
|
||
```
|
||
|
||
#### 列表与栈api
|
||
列表append操作是将元素追加到列表末尾,同时列表还支持pop操作,将列表末尾的元素作为栈顶元素弹出。
|
||
|
||
如果此时列表为空,那么调用pop方法将抛出异常
|
||
|
||
```py
|
||
temp = [1, "2", "san"]
|
||
|
||
|
||
print(temp.pop()) # san
|
||
print(temp.pop()) # 2
|
||
print(temp.pop()) # 1
|
||
print(temp.pop()) # IndexError: pop from empty list
|
||
```
|
||
|
||
还可以为pop方法指定一个下标,此时可以弹出任何位置的元素
|
||
```py
|
||
temp = [1, "2", "san"]
|
||
|
||
|
||
print(temp.pop(1)) # 2
|
||
print(temp.pop(0)) # 1
|
||
print(temp.pop(0)) # san
|
||
```
|
||
#### remove
|
||
在列表中,可以调用remove来移除列表中值为xxx的元素。
|
||
|
||
remove默认只会移除第一个匹配的元素
|
||
```py
|
||
temp = [2, 1, 2, 1, 2]
|
||
|
||
temp.remove(2)
|
||
print(temp) # [1, 2, 1, 2]
|
||
```
|
||
|
||
### 列表排序
|
||
#### sort
|
||
可以通过sort方法针对列表中的元素进行排序,sort方法会该表列表中的元素顺序
|
||
```py
|
||
temp = [2, 1, 2, 1, 2]
|
||
|
||
temp.sort()
|
||
print(temp) # [1, 1, 2, 2, 2]
|
||
```
|
||
|
||
如果想要逆向排序,可以为sort方法指定`reverse=True`
|
||
```py
|
||
temp = [2, 1, 2, 1, 2]
|
||
|
||
temp.sort(reverse=True)
|
||
print(temp) # [2, 2, 2, 1, 1]
|
||
```
|
||
|
||
#### sorted
|
||
如果不想改变原列表中的元素顺序,而是生成一个排好序的新列表,可以调用sorted函数
|
||
```py
|
||
temp = [2, 1, 2, 1, 2]
|
||
|
||
print(sorted(temp)) # [1, 1, 2, 2, 2]
|
||
print(sorted(temp, reverse=True)) # [2, 2, 2, 1, 1]
|
||
print(temp) # [2, 1, 2, 1, 2]
|
||
```
|
||
|
||
### 列表中顺序反转
|
||
如果不想对列表中元素进行排序,只是想逆序列表中的数据,可以调用reverse方法
|
||
```py
|
||
temp = [2, 1, 2, 1, 3]
|
||
|
||
temp.reverse()
|
||
print(temp) # [3, 1, 2, 1, 2]
|
||
```
|
||
### 获取列表长度
|
||
可以通过len函数获取列表的长度
|
||
```py
|
||
temp = [1,2,3]
|
||
|
||
temp.pop()
|
||
print(len(temp)) # 2
|
||
temp.pop()
|
||
print(len(temp)) # 1
|
||
temp.pop()
|
||
print(len(temp)) # 0
|
||
```
|
||
|
||
### 遍历列表
|
||
在python中,可以通过`for ... in ...`的形式来遍历列表中的元素
|
||
```py
|
||
temp = [1, 2, 3]
|
||
|
||
for e in temp:
|
||
print(e)
|
||
|
||
# 1
|
||
# 2
|
||
# 3
|
||
```
|
||
|
||
### range
|
||
在python中,可以通过range函数生成一系列数字,`range(m,n)`会生成`[m,n)`范围内的数字,可用于`fori`形式的遍历
|
||
```py
|
||
arr = ["1", "3", "2"]
|
||
|
||
for ind in range(0, len(arr)):
|
||
print(arr[ind])
|
||
|
||
# 1
|
||
# 3
|
||
# 2
|
||
```
|
||
可以通过range函数来创建数字列表
|
||
```py
|
||
print(list(range(0, 5))) # [0, 1, 2, 3, 4]
|
||
```
|
||
|
||
range也可以指定步长
|
||
```py
|
||
print(list(range(0, 7, 2))) # [0, 2, 4, 6]
|
||
```
|
||
|
||
### max, min, sum
|
||
针对数字型的列表,支持max、min、sum等函数来求最大值、最小值、总和
|
||
```py
|
||
arr = list(range(1, 101))
|
||
|
||
print(max(arr)) # 100
|
||
print(min(arr)) # 1
|
||
print(sum(arr)) # 5050
|
||
```
|
||
### 根据一个列表生成另一个列表
|
||
python中,根据`[expr(e) for e in list_a]`的语法,可以快速根据一个列表得到应一个列表,目标列表中的每个元素都来源于来源列表的映射
|
||
```py
|
||
arr = ['amd', 'nvidia']
|
||
graphic_msgs = ['fuck '+brand for brand in arr]
|
||
print(graphic_msgs) # ['fuck amd', 'fuck nvidia']
|
||
```
|
||
|
||
### 切片
|
||
列表的切片和字符串切片类似
|
||
```py
|
||
arr = [1, 2, 3, 4, 5]
|
||
print(arr[::2]) # [1, 3, 5]
|
||
|
||
print([e**2 for e in arr[::2]]) # [1, 9, 25]
|
||
```
|
||
|
||
### 列表复制
|
||
在python中,如果要复制列表,可以创建整个列表的切片
|
||
```py
|
||
arr = [1, 2, 3]
|
||
# 复制列表
|
||
arr_copied = arr[:]
|
||
|
||
print(arr_copied) # [1, 2, 3]
|
||
|
||
# 对复制后的列表进行写操作,并不会影响复制前的列表
|
||
arr_copied.pop()
|
||
|
||
print(arr_copied) # [1, 2]
|
||
print(arr) # [1, 2, 3]
|
||
```
|
||
|
||
## 元组
|
||
运行时列表中的元素可以被修改,如果想要让元素不可变,可以使用元组。
|
||
|
||
元组通过`(e1, e2, e3, ...)`形式来表示,和列表一样,元组也可以通过索引来访问。
|
||
|
||
但是元组中的元素无法复制,在执行赋值语句时会抛出异常。
|
||
```py
|
||
pos = (50, 100)
|
||
|
||
pos[0] = 125 # TypeError:'tuple' object does not support item assignment
|
||
```
|
||
|
||
## if
|
||
类似其他编程语言,python也支持if/else语法
|
||
```py
|
||
cars = ['audi', 'bmw', 'subaru', 'toyota']
|
||
for car in cars:
|
||
if car == 'bmw':
|
||
print(car.upper())
|
||
else:
|
||
print(car.title())
|
||
```
|
||
|
||
### and/or
|
||
python可以通过`and`和`or`操作符来拼接多个条件。
|
||
```py
|
||
age = 179
|
||
is_alive = True
|
||
|
||
if age < 0 or age > 150 and is_alive:
|
||
print("age wired")
|
||
```
|
||
|
||
### 列表中是否包含某值
|
||
如果想要检查列表中是否包含特定值,可以采用`xxx in list_a`的语法。
|
||
```py
|
||
arr = [1, 3, 2]
|
||
|
||
print(1 in arr) # True
|
||
```
|
||
### 列表中是否不包含某值
|
||
如果想要检查列表中是否不包含特定值,可以采用`xxx not in list_a`的语法。
|
||
```py
|
||
arr = [1, 3, 2]
|
||
|
||
print(1 not in arr) # False
|
||
```
|
||
|
||
### 多分支if/elif/else
|
||
python可以通过if/elif/else的语法实现多分支判断
|
||
```py
|
||
age = 40
|
||
if age < 20:
|
||
print("teen")
|
||
elif age < 40:
|
||
print("man")
|
||
else:
|
||
print("elder man")
|
||
```
|
||
|
||
## 字典
|
||
在python中,通过字典实现了其他语言中的Map数据结构。
|
||
|
||
```py
|
||
dic = {"name": "Ogura Asahi", "age": 17}
|
||
|
||
print(dic['name']) # Ogura Asahi
|
||
```
|
||
### 向字典中添加键值对
|
||
```py
|
||
dic = {"name": "Ogura Asahi", "age": 17}
|
||
|
||
dic['major'] = "student"
|
||
print(dic) # {'name': 'Ogura Asahi', 'age': 17, 'major': 'student'}
|
||
```
|
||
|
||
### 删除字典中的键值对
|
||
```py
|
||
dic = {"name": "Ogura Asahi", "age": 17}
|
||
|
||
del dic['age']
|
||
print(dic) # {'name': 'Ogura Asahi'}
|
||
```
|
||
|
||
### 字典遍历
|
||
字典遍历可以通过`for k, v in dic.items()`的形式完成
|
||
```py
|
||
dic = {"name": "Ogura Asahi", "age": 17}
|
||
|
||
for key, val in dic.items():
|
||
print("key = "+key+" , value = "+str(val))
|
||
```
|
||
如果只想遍历字典的key集合,可以通过`for k in dic.keys()`的方式
|
||
```py
|
||
dic = {"name": "Ogura Asahi", "age": 17}
|
||
|
||
for key in dic.keys():
|
||
print("key = "+key)
|
||
```
|
||
如果只想遍历字典的value集合,可以通过`for v in dic.values()`的形式
|
||
```py
|
||
dic = {"name": "Ogura Asahi", "age": 17}
|
||
|
||
for value in dic.values():
|
||
print("value = "+str(value))
|
||
```
|
||
### 按顺序遍历字典的key
|
||
通常,字典的key遍历顺序是不一定的。如果想要按排序后的顺序遍历key,可以采用如下方式:
|
||
```py
|
||
dic = {"name": "Ogura Asahi", "age": 17}
|
||
|
||
for key in sorted(dic.keys()):
|
||
print("key = "+str(key))
|
||
```
|
||
## while
|
||
```py
|
||
i = 0
|
||
|
||
while i < 10:
|
||
print(i)
|
||
i += 1
|
||
```
|
||
## 函数
|
||
函数可通过如下方式来定义:
|
||
```py
|
||
def fuck(brand, boss):
|
||
print("fuck you " + boss + " and your " + brand)
|
||
|
||
|
||
fuck("Nvidia", "Jensen Huang")
|
||
```
|
||
|
||
在调用函数时,可以打乱传入实参顺序,只需要传参时指定参数名称即可:
|
||
```py
|
||
def fuck(brand, boss):
|
||
print("fuck you " + boss + " and your " + brand)
|
||
|
||
|
||
fuck(boss="Jensen Huang", brand="Nvidia")
|
||
```
|
||
### 参数默认值
|
||
声明函数时,可以为参数指定默认值,故而在调用函数时,可以对有默认值的参数进行省略
|
||
```py
|
||
def fuck(boss, brand="Nvidia"):
|
||
print("fuck you " + boss + " and your " + brand)
|
||
|
||
|
||
fuck("Jensen Huang")
|
||
fuck(brand="Apple", boss="Cook")
|
||
```
|
||
### 接收多个参数
|
||
通过`*paramTup`的形式,python会将函数接收到的参数都存储在一个元组中。
|
||
```py
|
||
def fuck(*name_list):
|
||
msg = "fuck "
|
||
is_head = True
|
||
for name in name_list:
|
||
if not is_head:
|
||
msg += ", "
|
||
is_head = False
|
||
msg += name
|
||
print(msg)
|
||
|
||
|
||
fuck("Nvidia", "Amd")
|
||
```
|
||
## 文件操作
|
||
### 文件读取
|
||
```py
|
||
with open('pi_digits.txt') as file_object:
|
||
contents = file_object.read()
|
||
print(contents)
|
||
```
|
||
### 写入文件
|
||
```py
|
||
filename = 'programming.txt'
|
||
with open(filename, 'w') as file_object:
|
||
file_object.write("I love programming.")
|
||
file_object.write("I love creating new games.")
|
||
```
|
||
|
||
### 文件末尾追加
|
||
```py
|
||
filename = 'programming.txt'
|
||
with open(filename, 'a') as file_object:
|
||
file_object.write("I also love finding meaning in large datasets.\n")
|
||
file_object.write("I love creating apps that can run in a browser.\n")
|
||
```
|
||
## 异常处理
|
||
在python中,可以通过如下语法来进行异常处理
|
||
```py
|
||
try:
|
||
# code block
|
||
pass
|
||
except ErrorType1:
|
||
# error type 1 handling code block
|
||
pass
|
||
except ErrorType2:
|
||
# error type 2 handling code block
|
||
pass
|
||
except Exception as result:
|
||
# handle other exception types
|
||
pass
|
||
else:
|
||
# code block that no error occurs
|
||
pass
|
||
finally:
|
||
# code block executed whether exception occurs
|
||
pass
|
||
```
|
||
|
||
### 抛异常
|
||
#### 捕获异常后重新抛出异常
|
||
如果python在捕获异常后需要重新对异常进行抛出,可以使用`raise`关键字
|
||
```py
|
||
try:
|
||
m = 10/0
|
||
except Exception as e:
|
||
print(e)
|
||
raise
|
||
finally:
|
||
print("handle correctly")
|
||
```
|
||
#### 主动抛出异常
|
||
主动抛出异常时,也可使用`raise`关键字
|
||
```py
|
||
try:
|
||
raise Exception("fucking Nvidia raised their price!")
|
||
except Exception as e:
|
||
print(e)
|
||
finally:
|
||
print("my wallet is empty!")
|
||
```
|
||
|
||
## 数据存储
|
||
### json.dump
|
||
可以通过`json.dump`方法将内容以json的格式存储到文件中:
|
||
```py
|
||
import json
|
||
|
||
|
||
def save_as_json(data, fd):
|
||
json.dump(data, fd)
|
||
|
||
|
||
waifu = {
|
||
"name": "Touma Kazusa",
|
||
"job": "Student",
|
||
"gender": "female",
|
||
"age": 17
|
||
}
|
||
|
||
is_save_success = True
|
||
try:
|
||
with open("shiro.json", "w") as shiro_fd:
|
||
save_as_json(waifu, shiro_fd)
|
||
except Exception as e:
|
||
print(e)
|
||
is_save_success = False
|
||
exit(1)
|
||
finally:
|
||
if is_save_success:
|
||
print("save success!")
|
||
```
|
||
### json.load
|
||
可以通过`json.load`方法读取文件中的json格式内容:
|
||
```py
|
||
import json
|
||
|
||
|
||
def read_as_json(fd):
|
||
return json.load(fd)
|
||
|
||
|
||
is_read_success = True
|
||
try:
|
||
with open("shiro.json", "r") as shiro_fd:
|
||
r_obj = read_as_json(shiro_fd)
|
||
print(r_obj)
|
||
except Exception as e:
|
||
print(e)
|
||
is_read_success = False
|
||
exit(1)
|
||
finally:
|
||
if is_read_success:
|
||
print("read success!")
|
||
```
|
||
## http api
|
||
python安装requests包之后,可以访问http接口
|
||
```py
|
||
import math
|
||
import requests
|
||
import time
|
||
|
||
try:
|
||
body = requests.get("https://api.m.taobao.com/rest/api3.do", {
|
||
"api": "mtop.common.getTimestamp"
|
||
}).json()
|
||
ts = body['data']['t']
|
||
t = time.localtime(math.trunc(int(ts) / 1000))
|
||
time_str = time.strftime("%Y-%m-%d %H:%M:%S %z", t)
|
||
print(time_str)
|
||
except Exception as e:
|
||
print(e)
|
||
raise
|
||
```
|
||
|
||
## 多线程
|
||
python可以通过引入threading和concurrent.futures两个包来引入多线程:
|
||
```py
|
||
import math
|
||
import time
|
||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||
import threading
|
||
|
||
import requests
|
||
|
||
ts_arr = []
|
||
lock = threading.Lock()
|
||
|
||
|
||
def query_ts():
|
||
try:
|
||
body = requests.get("https://api.m.taobao.com/rest/api3.do", {
|
||
"api": "mtop.common.getTimestamp"
|
||
}).json()
|
||
except Exception as e:
|
||
print(e)
|
||
raise
|
||
|
||
|
||
def query_ts_once():
|
||
ts_beg = time.time_ns()
|
||
query_ts()
|
||
ts_end = time.time_ns()
|
||
ts_spend = math.trunc((ts_end - ts_beg) / 1000000)
|
||
with lock:
|
||
ts_arr.append(ts_spend)
|
||
|
||
|
||
def stress_test(test_cnt):
|
||
with ThreadPoolExecutor(max_workers=32) as executor:
|
||
i = 0
|
||
f_list = []
|
||
while i < test_cnt:
|
||
f_t = executor.submit(query_ts_once)
|
||
f_list.append(f_t)
|
||
i += 1
|
||
as_completed(f_list)
|
||
|
||
|
||
stress_test(100)
|
||
print(f"max ts : {max(ts_arr)} ms")
|
||
print(f"min ts : {min(ts_arr)} ms")
|
||
print(f"avg ts : {sum(ts_arr) / len(ts_arr)} ms")
|
||
print(ts_arr)
|
||
```
|
||
|
||
## linux命令交互
|
||
如果想要调用系统(linux)的命令,可以使用subprocess模块。
|
||
```py
|
||
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
|
||
```
|
||
调用示例如下:
|
||
```py
|
||
ret = subprocess.run(['ls', '-l'], capture_output=True, text=True)
|
||
print(ret.stdout)
|
||
```
|
||
输出如下:
|
||
```bash
|
||
total 4
|
||
-rwxrwxrwx 1 asahi asahi 110 May 4 03:18 main.py
|
||
-rwxrwxrwx 1 asahi asahi 73 May 4 01:10 shiro.json
|
||
drwxrwxrwx 1 asahi asahi 4096 Feb 7 21:39 venv
|
||
```
|
||
|
||
|
||
|