python中,使用input函数读取控制台的一行输入
# 输入为: 1 2 3 4 5
a = input()
print(a)
# a = '1 2 3 4 5'input返回的是一个string
a, b = map(int, input().split(' '))
print(f"{a} and {b}")import sys
# 读一行
input = lambda: sys.stdin.readline().strip()
# 全读,直到EOF为止
input = lambda: sys.stdin.read().strip()相当于c++解绑输入输出并关闭流同步
直到捕获到EOF
while True:
try:
line = input()
except EOFError:
break
# 处理每一行
print(line)import sys
input = lambda: sys.stdin.readline().strip()
while True:
line = input()
if line == "": # 当读到空字符串时认为已经到达 EOF
break
# 对每一行进行处理
print(line)读到单独的一行换行符也会认为结束,如果不是需要特判
import sys
# 定义 input
input = lambda: sys.stdin.readline()
while True:
line = input()
# 判断是否到达 EOF
if line == "":
break
# 如果是一个仅包含换行符的空行,直接打印
if line == "\n":
print(line, end="") # 保留原样输出换行符
else:
# 对非空行去除两侧空白,再处理
line = line.strip()
# 处理后的行再加上一个换行符输出
print(line, end="\n")默认结尾会加换行符,可以用end更改
print("有生命\n便有希望",end="")
print("!")用间隔符可以指定print的每一个元素的间隔
print("谋事在人", "成事在天", "有生命便有希望", sep="&")假如我们最后要把数组里面的print一遍
import sys
a = [1, 2, 3, 4, 5, 6, 7]
input = lambda: sys.stdin.readline().strip()
output = [str(i) for i in a]
sys.stdout.write("\n".join(output) + "\n")
sys.stdout.write(" ".join(output) + "\n")
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 1 2 3 4 5 6 7c++的这种:
map<int, vector<int>> v;
v.insert({1, {}});
v[1].push_back(23);可以用:
defaultdict(list):
from collections import defaultdict
mp = defaultdict(list)
for i in range(10):
mp[i].append(i * 2)
mp[10 - i].append(i * 2)
print(mp.items())setdefault:
from collections import defaultdict
mp = {}
for i in range(10):
mp.setdefault(i, []).append(i * 2)
mp.setdefault(10 - i, []).append(i * 2)
print(mp.items())dict_items([(0, [0]), (10, [0]), (1, [2, 18]), (9, [2, 18]), (2, [4, 16]), (8, [4, 16]), (3, [6, 14]), (7, [6, 14]), (4, [8, 12]), (6, [8, 12]), (5, [10, 10])])像cpp那样的多维vector。
vector<int> v[N];
v[1].push_back(1);v = [[] for _ in range(10)]
v[a].append(Edge(b, c))像c++里面的upper_bound(begin, end, value)差不多
bisect_left(a, x, lo=0, hi=len(a))在从小到大排好序的列表 a 中查找第一个不小于 x(即大于或等于 x)的位置
import bisect
a = [10, 20, 30, 30, 40, 50]
index = bisect.bisect_left(a, 30)
print(index) # 输出 2,因为 a[2] 是第一个大于等于30的元素bisect_right(a, x, lo=0, hi=len(a))或其别名bisect(a, x, lo=0, hi=len(a))在从小到大排好序的列表 a 中查找第一个大于 x 的位置
import bisect
a = [10, 20, 30, 30, 40, 50]
index = bisect.bisect_right(a, 30)
print(index) # 输出 4,因为 a[4] 是第一个大于30的元素降序表翻转一下再找即可
python中提供了高层的queue库来实现线程安全的队列栈优先队列等
也有更底层的collections.deque和heapq
前者:
from queue import *
# —— FIFO 队列 ——
q = Queue()
q.put(1) # 入队 1
q.put(2) # 入队 2
print("FIFO 队列 peek: front =", q.queue[0], "rear =", q.queue[-1])
print("FIFO 出队:", q.get()) # 出队 -> 1
print("FIFO 出队:", q.get()) # 出队 -> 2
# —— LIFO 栈 ——
stack = LifoQueue()
stack.put("a") # 入栈 'a'
stack.put("b") # 入栈 'b'
print("LIFO 栈 peek: top =", stack.queue[-1], "bottom =", stack.queue[0])
print("LIFO 出栈:", stack.get()) # 出栈 -> 'b'
print("LIFO 出栈:", stack.get()) # 出栈 -> 'a'
# —— 优先级队列(最小堆)——(只放入可直接比较的数字)
pq = PriorityQueue()
pq.put(5)
pq.put(1)
pq.put(3)
print("最小堆 peek:", pq.queue[0])
print("最小堆 出队:", pq.get()) # 出队 -> 1
print("最小堆 出队:", pq.get()) # 出队 -> 3
print("最小堆 出队:", pq.get()) # 出队 -> 5
# —— 大根堆(最大堆)——(实现方法:存入的数字取负)
max_pq = PriorityQueue()
max_pq.put(-5)
max_pq.put(-1)
max_pq.put(-3)
# peek操作:取出堆顶的负数,再取相反数
print("大根堆 peek:", -max_pq.queue[0])
# 出队时再取负数以还原原来的值
print("大根堆 出队:", -max_pq.get())
print("大根堆 出队:", -max_pq.get())
print("大根堆 出队:", -max_pq.get())后者:
from collections import *
import heapq
# —— FIFO 队列 ——
dq = deque()
dq.append(1) # 入队尾 1
dq.append(2) # 入队尾 2
print("deque FIFO peek: front =", dq[0], "rear =", dq[-1])
print("deque FIFO 出队:", dq.popleft()) # 出队头 -> 1
print("deque FIFO 出队:", dq.popleft()) # 出队头 -> 2
# —— LIFO 栈 ——
stk = deque()
stk.append("a") # 入栈 'a'
stk.append("b") # 入栈 'b'
print("deque LIFO peek: top =", stk[-1], "bottom =", stk[0])
print("deque LIFO 出栈:", stk.pop()) # 出栈 -> 'b'
print("deque LIFO 出栈:", stk.pop()) # 出栈 -> 'a'
# —— 最小堆 ——
# 用列表充当容器
min_heap = []
heapq.heappush(min_heap, 5)
heapq.heappush(min_heap, 1)
heapq.heappush(min_heap, 3)
print("heapq 最小堆 peek:", min_heap[0])
print("heapq 最小堆 出堆:", heapq.heappop(min_heap)) # -> 1
print("heapq 最小堆 出堆:", heapq.heappop(min_heap)) # -> 3
print("heapq 最小堆 出堆:", heapq.heappop(min_heap)) # -> 5
# —— 大根堆 ——(存负数实现)
max_heap = []
heapq.heappush(max_heap, -5)
heapq.heappush(max_heap, -1)
heapq.heappush(max_heap, -3)
print("heapq 大根堆 peek:", -max_heap[0])
print("heapq 大根堆 出堆:", -heapq.heappop(max_heap)) # -> 5
print("heapq 大根堆 出堆:", -heapq.heappop(max_heap)) # -> 3
print("heapq 大根堆 出堆:", -heapq.heappop(max_heap)) # -> 1后者时间效率更高
sorted函数排序一切可迭代对象,返回一个新的对象
list.sort是原地排序
自定义排序:
使用key关键字
L = ["pear", "apple", "banana", "kiwi", "plum"]
L.sort(key=len) # 按照长度排序
print(L) # 输出:['kiwi', 'pear', 'plum', 'apple', 'banana']L = ["pear", "apple", "banana", "kiwi", "plum"]
L.sort(key=lambda s: s[-1])
print(L) # 输出:['banana', 'kiwi', 'apple', 'pear', 'plum']lambda s: s[-1] 定义了一个匿名函数,输入是字符串 s,返回其最后一个字符(例如 "pear" 返回 "r"),排序基于这些字符。
也可以自定义命名函数
def count_vowels(s):
vowels = "aeiouAEIOU"
return sum(1 for char in s if char in vowels)
L = ["pear", "apple", "banana", "kiwi", "plum"]
L.sort(key=count_vowels)
print(L) # 输出:['kiwi', 'plum', 'pear', 'apple', 'banana']key可以等于一个元组,用来复合排序,先按照前面的条件,再按照后面的条件排序
L = ["pear", "apple", "banana", "kiwi", "plum"]
L.sort(key=lambda s: (len(s), s))
print(L) # 输出:['kiwi', 'pear', 'plum', 'apple', 'banana']Python 按元组的顺序比较:先比较第一个元素(长度),如果相等再比较第二个元素(字符串本身)。
开reverse会颠倒顺序
L = ["pear", "apple", "banana", "kiwi", "plum"]
L.sort(key=lambda s: (len(s), s))
print(L)
L.sort(key=lambda s: (len(s), s), reverse=True)
print(L)函数体内先从内部寻找变量,找不到再去全局找。在函数内使用全局变量需要声明 global 。
cnt = 0
def dfs(u):
global cnt
passv = [[] for _ in range(10)]
path = [0] * 10
st = [False] * 10
ans = int(1e18 + 10)下标从 1 开始再排序怎么做
m = int(input())
# 模拟 1-based,先创建 m+1 个元素的列表,a[0] 不用
a = [None] * (m + 1)
# 从 1 到 m 读入
vals = list(map(int, input().split()))
for i in range(1, m+1):
a[i] = vals[i-1]
# 对 a[1:] 这段区间排序,排序结果再放回 a[1:]
a[1:] = sorted(a[1:])
# 此时 a[1] … a[m] 就是排好序的
for i in range(1, m+1):
print(a[i], end=' ')
print()a = 18
b = 30
a, b = b, a类似于结构体
from dataclasses import dataclass
@dataclass
class Item:
id: int
size: int
name: str
def main():
n = int(input())
items = []
for _ in range(n):
_id, sz, nm = input().split()
items.append(Item(int(_id), int(sz), nm))
# 按 size 排序
items.sort(key=lambda x: x.size)
# 输出
for it in items:
print(it.id, it.size, it.name)
if __name__ == "__main__":
main()例子:邻接表:
@dataclass
class Edge:
to: int
w: int
v = [[] for _ in range(10)]
for _ in range(m):
a, b, c = map(int, input().split(" "))
v[a].append(Edge(b, c))
v[b].append(Edge(a, c))日期处理,格式化匹配,快速计算两个日期的差值
%Y: 四位数的年份(例如,2019)。%y: 两位数的年份(例如,19)。%m: 两位数的月份(01 至 12)。%d: 两位数的日期(01 至 31)。%H: 两位数的小时(24 小时制,00 至 23)。%I: 两位数的小时(12 小时制,01 至 12)。%M: 两位数的分钟(00 至 59)。%S: 两位数的秒钟(00 至 59)。%f: 微秒(000000 至 999999)。%p: 上/下午标记(AM 或 PM)。%z: UTC 偏移,例如 +0000。%Z: 时区名称。%j: 一年中的第几天(001 至 366)。%U: 一年中的星期数(星期日为第一天,00 至 53)。%W: 一年中的星期数(星期一为第一天,00 至 53)
from datetime import datetime
# 示例 1: 仅日期
dt1 = datetime.strptime('2019-11-05', '%Y-%m-%d')
print(dt1) # 输出: 2019-11-05 00:00:00
# 示例 2: 仅时间
dt2 = datetime.strptime('09:30:50', '%H:%M:%S')
print(dt2) # 输出: 1900-01-01 09:30:50
# 示例 3: 日期和时间
dt3 = datetime.strptime('2019-11-05 09:30:50', '%Y-%m-%d %H:%M:%S')
print(dt3) # 输出: 2019-11-05 09:30:50from datetime import datetime
# 定义两个日期时间对象
dt1 = datetime.strptime('2019-11-05 09:30:50', '%Y-%m-%d %H:%M:%S')
dt2 = datetime.strptime('2020-01-10 15:45:00', '%Y-%m-%d %H:%M:%S')
# 计算两个日期时间的差值
delta = dt2 - dt1
print(delta) # 输出: 66 days, 6:14:10
print(delta.days) # 输出: 66 (天)
print(delta.seconds) # 输出: 22450 (秒) —— 不包括天数转换成秒的部分
# 如果想获取总秒数,可以使用 total_seconds()
print(delta.total_seconds()) # 输出: 总的秒数可以直接用列表乘法实现
l = [1, 2, 3, 4, 5]
l = [0] * 10
l = [0] * 20
print(l)import sys
sys.setrecursionlimit(1000000000)