pygame基础操作学习差不多学了一下,但是python基础限制不能进一步的深度学习pygame的高级操作只好继续打python基础,打算用七天时间学完python基础,然后继续学习pygame项目开发
Python在字典中储存列表
用for
循环访问键的时候,对应的值为列表list
,若要访问列表的值,再嵌套一个for
循环即可:
favorite_languages = {
'jen' : ['Python', 'ruby'],
'sarah' : ['c'],
'edward' : ['ruby', 'go'],
'phil' : ['python', 'haskell'],
}
for name, languages in favorite_languages.items():
if len(languages) > 1:
print(f"\n{name.title()}'s favorite languages are:")
for language in languages:
print(f"\t{language.title()}")
elif len(languages) == 1:
print(f"\n{name.title()}'s favorite languages is {languages[0].title()}")
当print
函数中要输出的字符串过长时,都罗列在同一行不是一个明智的选择,换行的操作:
在每行末尾加上引号,同时对于出去第一行外的其他各行采取行首加"
,并缩进:
print(f"You ordered a pizza-crust pizza "
"with the following toppings:")
在字典中储存字典
代码之间的嵌套更为复杂,例如:
每个用户都有独立的用户名和个人信息,要用一个字典将其储存下来,那么字典里的每一个键值对都是一个字典:
users = {
'aeinstein' : {
'first' : 'albert',
'last' : 'einstein',
'location' : 'princeton',
},
'mcurie' : {
'first' : 'marie',
'last' : 'curie',
'location' : 'paris',
},
}
for username, user_info in users.items():
print(f"\nUsername: {username}")
full_name = f"{user_info['first']} {user_info['last']}"
location = user_info['location']
print(f"\tFull name: {full_name.title()}")
print(f"\tLocation: {location.title()}")
复杂度明显提升。
练习:
pet_1 = {
'name' : 'chaiquan',
'color' : 'yellow',
'owner' : 'lubenwei',
}
pet_2 = {
'name' : '2ha',
'color' : 'white',
'owner' : 'qiezi',
}
pets = [pet_1, pet_2]
for pet in pets:
print(f"Name: {pet['name']}\nColor: {pet['color']}\nOwner: {pet['owner']}\n")
并查集:
常用于判断两个元素是否来自同一个集合或者合并两个集合的操作。
处理思想: 将两个集合抽象成两棵树(不一定是二叉树,可能是多叉树)
时间复杂度:近乎 O ( 1 ) O(1) O(1)
开一个数组,储存树中的每个节点的父亲节点,p[x]
表示x的父亲节点,且每棵树的树根编号就是该所属集合的编号。
问题一: 如何判断树根?(找祖源)
if (p[x] == x) --> True
else --> False
问题二: 如何求x的集合编号?
while (father[x] != x) x = p[x];
问题三: 如何合并两个集合?
// p[x] 是 x的集合编号, p[y] 是 y 的集合编号
p[x] = y
例题:
合并集合
代码:
#include<iostream>
using namespace std;
const int N = 100010;
int n, m;
int father[N];
int find (int x){
if (father[x] != x) father[x] = find(father[x]);
return father[x];
}
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) father[i] = i;
while (m -- ){
int a, b;
char op[2];
scanf("%s%d%d", op, &a, &b);
if (op[0] == 'M') father[find(a)] = find(b);
else {
if (find(a) == find(b)) puts("Yes");
else puts("No");
}
}
return 0;
}
例题二:
连通块中点的数量
代码:
#include<iostream>
using namespace std;
const int N = 100010;
int father[N];
int n, m, sizes[N];
int find(int x){
if (father[x] != x) father[x] = find(father[x]);
return father[x];
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ ) {
father[i] = i;
sizes[i] = 1;
}
while (m -- ){
char op[5];
int a, b;
scanf("%s", op);
if (op[0] == 'C') {
scanf("%d%d", &a, &b);
if(find(a) == find(b)) continue;
sizes[find(b)] += sizes[find(a)];
father[find(a)] = find(b);
}
else if (op[1] == '1'){
scanf("%d%d", &a, &b);
if(find(a) == find(b)) puts("Yes");
else puts("No");
}
else if (op[1] == '2'){
scanf("%d", &a);
find(a);
printf("%d\n", sizes[find(a)]);
}
}
}
注解:size[N]
储存的是该集合中(连通块)中的点的数量,但是只有祖宗节点的size[]
才有实际意义