1. 程式人生 > 實用技巧 >AGC029F Construction of a tree

AGC029F Construction of a tree

一、變數

1、什麼是變數

變:變化

量:指的是事物的狀態

變數:是一種可以反映出狀態變化的一種機制,比如人的年齡,性別,等級,金錢等

2、為什麼要有變數

為了讓計算機能夠像人一樣去記憶事物的某種狀態,並且狀態是可以發生變化的,程式執行的本質就是一系列狀態的變化

變數的命名規範?

  1. 變數名只能是 字母、數字或下劃線的任意組合
  2. 變數名的第一個字元不能是數字
  3. 關鍵字不能宣告為變數名
  4. 變數名不能為中文

變數的三大特性:
值:value
記憶體地址:id
變數的型別:type

二、格式化輸出

定義:就是把一段字串裡面的某些內容替換掉之後再輸出。

%s 佔位符:可以接受任意型別的值
%d 佔位符:只能接受整數型別
# 按照順序傳值 name = input('your name:') age = input('your age:') print('my name is %s,my age is %s' %(name,age)) print('my name is %s,my age is %s' %('egon',18)) #format name = input('your name:') age = input('your age:') print("my name is {},my age is {}".format(name,age)) print('my name is {name},my age is {age}
'.format(name=name,age=age)) #f'{}' print(f'my name is {name},my age is {age}')

三、基本資料型別

1.整型int

用途:年齡,等級,號碼

#定義方式:

age = 10   #age = int(10)

2.浮點型float

用途:身高,體重,薪資

定義方式:
height =1.81   #height =float(1.81)


#十進位制轉其他進位制

print(bin(3))     #ob11    十進位制轉二進位制

print(oct(8))     #0o10    十進位制轉八進位制
print(hex(16)) #0x10 十進位制轉十六進位制

3.字串型別str

用來表示名字、年齡等描述性的資訊(資料)
定義方式:
str:包含在引號內的一串字元
# 字串拼接(+,*)是開闢一個新的記憶體空間,將你拼接之後的值存進去
s1 = 'hello '
s2 = 'world'
print(s1 + s2)  #hello world

print(s1*3)  #hello hello hello 


常用操作+內建方法:

優先掌握的操作:
1、按索引取值(正向取+反向取): **只能取不能改**
name = "baohan"
print(name[0])    #正向取
print(name[-1])   #反向取
print(type(name[-1]))   #<class 'str'>

2、切片(顧頭不顧尾,預設步長為1)
msg = "my name is Bob"
print(msg[0:6])
print(msg[0:6:2])  #m a
#瞭解:
#print(msg[0:5:1])
#print(msg[3:1,-1])
#print(msg[-1:-5:-1])
msg = 'alex is sb'
print(msg[0:])  #取全部
print(msg[::-1])  #順序全部倒過來

3、長度len():獲取當前資料中元素的個數
msg = 'my name is Bob'
print(len(msg))   #字元的個數 

4、成員運算in 和 not in
msg = 'my name is Bob'
print("my"in msg)  #True
print("name" not in msg)   #False

5、迴圈  for迴圈適用於字串,列表,字典,元組,集合
msg = 'alex is sb'
#for i in msg:
    #print(i)
i = 0
while i < len(msg):
    print(msg[i])
    i+=1

6、strip():移除空白 
name = input ('你的使用者名稱:').strip()
print(name)

7、split():對字串進行切分,可以指定切分的分隔符,返回的是一個列表
info = 'bob:123:admin'
res = info.split(':')
print(res,type(res))  #切完是列表型別
print(res[0])    #bob


    
需要掌握的操作:
1、 strip,lstrip,rstrip
print('**sss*****'.strip("*"))    #移除兩邊的*
print('**sss*****'.lstrip("*"))   #移除右邊的*

2、lower,upper:轉字串裡字元的大小寫
name1 = "egon"
name2 = "ALEX"
print(name1.upper())
print(name2.lower())

3、startswith,endswith  判斷字串是否以括號內指定的字元開頭、結尾,返回的是布林值True或False
info = "my name is bob"
print(info.startswith('m'))
print(info.startswith('my'))
print(info.endswith('b'))

4、format的三種用法
1)類似於%s的用法,傳入的值與{}一一對應
s1 = "my name is {},my age is {}".format("bob",18,19)
print(s1)

2)把format傳入的多個值當作一個列表,然後用{索引}取值
s2 = "my name is {0},my age is {1}".format("bob",18)
print(s2)

3)format括號內傳引數可以完全打亂順序,但根據鍵值對傳入指定引數
s3 = "my name is {name},my age is {age}".format(name="bob",age=18)
print(s3)

5、split,rsplit 
info = "get|bob|hobby"
print(info.split("|"))   #預設從左邊開始切分
print(info.split("|",1))   #可以指定切分的次數
print(info.rsplit("|",1))  #從右邊開始切分

6、join 將(列表)中每個元素按照""裡的內容為分隔符號進行拼接(傳入的列表內只能是字串)
l1 = ['get', 'bob', 'hobby']
print("+".join(l1))  #get+bob+hobby

7、f-string:通過大括號接受變數,在字串前面一定要加一個小寫的f,在python3.6以後才有

8、replace 將字串中的元素進行替換
info = "my name is egon,egon is handsome"
print(info.replace('egon','bob'))
print(info.replace('egon','bob',1))  #語法:replace('舊內容','新內容',修改的個數)

9、isdigit 判斷字串是否是整型,返回結果為布林值
age = "18"
print(age.isdigit())    #True
age = "19.1"
print(age.isdigit())    #False

print('sdaw'.isdigit())    #False

inp = input(">>>:")
if inp.isdigit():
    inp = int(inp)
    if inp == 10:
        print("right")
else:
    print("輸入格式錯誤")

瞭解的知識點:
# 1、find:查詢當前字串中某個元素的位置,返回索引,找不到返回-1
msg='tony say hello'
msg.find('o',1,3)  # 在索引為1和2(顧頭不顧尾)的字元中查詢字元o的索引
# 2、index:同find,但在找不到時會報錯
msg.index('e',2,4) # 報錯ValueError
# 3、rfind與rindex:略
# 4、count:統計當前字串中某一個元素出現的次數
msg = "hello everyone"
msg.count('e')  # 統計 e 出現的次數
# 5、center居中對齊,ljust左對齊,rjust右對齊,zfill填充0
name='tony'
name.center(30,'-')  # 總寬度為30,字串居中顯示,不夠用-填充
>>>-------------tony-------------
name.ljust(30,'*')  # 總寬度為30,字串左對齊顯示,不夠用*填充
>>>tony**************************
name.rjust(30,'*')  # 總寬度為30,字串右對齊顯示,不夠用*填充
>>>**************************tony
name.zfill(50)  # 總寬度為50,字串右對齊顯示,不夠用0填充
>>>0000000000000000000000000000000000000000000000tony
#6、expandtabs 
msg='abc\tdef' #製表符
print(msg.expandtabs(3))
#7、captalize():只有首字母是大寫
#8、swapcase():大小寫反轉
#9、title():每個單詞的首字母大寫

#10、is數字系列
#在python3中
num1 = b'4' #bytes
num2 = u'4' #unicode,python3中無需加u就是unicode
num3 = '' #中文數字
num4 = '' #羅馬數字

num1.isdigit()  #True
num2.isdigit()  #True
num3.isdigit()  #False
num4.isdigit()  #False

總結:
    最常用的是isdigit,可以判斷bytes和unicode型別,這也是最常見的數字應用場景
    如果要判斷中文數字或羅馬數字或unicode,則需要用到isnumeric
    isdecimal:只能用來判斷unicode
#11 is其他
name = 'tony123'
name.isalpha(): #字元全由字母組成
>>> True
name.isalnum(): #字元由字母或數字組成
>>> True
name.islower()  # 字串是否是純小寫
>>> True
name.isupper()  # 字串是否是純大寫
>>> False
name.isspace()  # 字串是否全是空格
>>> False
name.istitle()  # 字串中的單詞首字母是否都是大寫
>>> False

字串前面加一個小寫的r,代表轉義
print(r'hello\n world')
\t   輸入一個 製表符,協助在輸出文字時垂直方向保持對齊
print("1\t2\t3")    
print("10\t20\t30")
\n   換行符
\"   可以輸出一個"  
\\   就表示一個 \

4.列表list:

型別轉換:

但凡能被for迴圈遍歷的資料型別都可以傳給list()轉換成列表型別,list()會跟for迴圈一樣遍歷出資料型別中包含的每一個元素然後放到列表中
>>> list('wdad') # 結果:['w', 'd', 'a', 'd'] 
>>> list([1,2,3]) # 結果:[1, 2, 3]
>>> list({"name":"jason","age":18}) #結果:['name', 'age']
>>> list((1,2,3)) # 結果:[1, 2, 3] 
>>> list({1,2,3,4}) # 結果:[1, 2, 3, 4]
常用操作:
1、索引取值:(正反都可以取,即可存也可取)
user_info = ['egon',18,['football','eat','sleep']]
print(user_info[2][0])
>>> football

2、索引切片  切出來的也是列表
my_friends = ['tony', 'jason', 'tom', 4]
print(my_friends[0:4:2])   #第三個引數2代表步長
>>>['tony', 'tom']

3、長度len(): 獲取列表中元素的個數
my_friends = ['tony', 'jason', 'tom', 4]
len(my_friends)
>>>4

4、成員運算in和not in
my_friends = ['tony', 'jason', 'tom', 4]
'tony' in my_friends
>>>True
'egon' in my_friends
>>>False

5、迴圈 #迴圈遍歷my_friends列表裡面的值
#依賴索引
stus = ['bob','alex','egon']
i = 0
while i <len(stus):
    print(stus[i])
    i+=1

#不依賴於索引
for i in my_friends:
    print(i) 

內建方法:
1、新增
# append(): 列表尾部追加值,一次性只能新增一個值
l1 = ['a','b','c']
l1.append('d')
print(l1)
>>>['a', 'b', 'c', 'd']

# insert(): 插入值,通過索引指定插入的位置
l1 = ['a','b','c']
l1.insert(0,"first")  # 0表示按索引位置插值
print(l1)
>>>['first', 'a', 'b', 'c']

# extend(): 一次性在列表尾部新增多個元素
l1 = ['a','b','c']
l1.extend(['a','b','c'])
print(l1)
>>>['a', 'b', 'c',  'a', 'b', 'c']

2、刪除
2.1 remove():刪除指定的值,只能刪一個,沒有返回值
l = [11,22,33,22,44]
res=l.remove(22) # 從左往右查詢第一個括號內需要刪除的元素
print(res)
>>>None
2.2 pop()預設從列表最後一個元素開始刪,並將刪除的值返回,括號內可以通過加索引值來指定刪除元素
l = [11,22,33,22,44]
res=l.pop()
print(res)
>>>44

res=l.pop(1)
print(res)
>>>22

2.3 del 徹底刪除
l = [11,22,33,44]
del l[2]  # 刪除索引為2的元素
print(l)
>>>[11,22,44]

3、reverse()顛倒列表內元素順序
l = [11,22,33,44]
l.reverse() 
print(l)
>>>[44,33,22,11]

4、sort()給列表內所有元素排序,排序時,列表元素之間必須是相同資料型別,不可混搭,否則報錯
# 預設從小到大排序
# 大前提:只能同類型直接比較大小,對於有索引值的直接比較是按照位置一一對應進行比較的
l = [11,22,3,42,7,55]
l.sort()
print(l)
>>>[3, 7, 11, 22, 42, 55]  

l = [11,22,3,42,7,55]
l.sort(reverse=True)  # reverse用來指定是否跌倒排序,預設為False
print(l)
>>> [55, 42, 22, 11, 7, 3]

5、sorted():python的內建函式,在排序時生成一個新列表,原資料不變

6、count():統計當前列表內指定元素的個數
l = [11,22,3,42,7,55,11]
print(l.count(11))
>>>2

7、index():獲取當前指定元素的索引值,還可以指定查詢範圍
l = [11,22,3,42,7,55,11]
print(l.index(11,1,7))
>>>6

8、clear():清空列表資料
l = [11,22,3,42,7,55,11]
l.clear()
print(l)
>>>[]

補充知識點:

#佇列:先進先出 
l1 =[]                                 
l1.append(1)
l1.append(2)
l1.append(3)
print(l1)
l1.pop(0)
print(l1)
l1.pop(0)
l1.pop(0)
print(l1)

#堆疊:先進後出
l1 =[]
l1.append(1)
l1.append(2)
l1.append(3)
print(l1)
l1.pop()
print(l1)
l1.pop()
l1.pop()
print(l1)

5.字典dict

定義:通過{ }來儲存資料,通過key:value來定義鍵值對資料,每個鍵值對中間用逗號分隔開,其中value可以是任意型別,而key一定要是不可變型別(數字,字串)。

字典的三種定義方式:

1、d1 = {'name':'bob','age':18}
2、d2 = dict({'name':'bob'})
3、#瞭解  zip:  
l1 = ['name','bob']
l2 = ['age','18']
z1 = zip(l1,l2)
print(dict(z1))
常用方法:

1.1、按照key:value對映關係取值(可存可取)
user_info = {'name':'egon','age':18,'hobbies':['football','eat','sleep']}
print(user_info['age'])
>>>18
print(user_info['hobbies'][0])
>>>football

1.2、賦值:如果key原先不存在於字典,則會新增key:value
dic = {'name':'egon'}
dic['age'] = 18
print(dic)
>>>{'name': 'egon', 'age': 18}

1.3 賦值:如果key原先存在於字典,則會修改對應value的值
dic = {'name':'egon','age':18}
dic['name'] = 'tony'
print(dic)
>>>{'name': 'tony', 'age': 18}

2、成員運算:in , not in #預設判斷某個值是否為字典的key
user_info = {'name':'egon','age':18}
print("name" in user_info)
>>>True

3、len():#獲取當前字典中鍵值對的個數
user_info = {'name':'egon','age':18}
print(len(user_info))
>>>2

4、for迴圈
4.1 預設遍歷的是字典的key
for key in user_info:
print(key)
>>>name
>>>age

4.2 只遍歷key
for i in user_info.keys():
    print(i)
>>>name
>>>age

4.3 只遍歷value
user_info ={'name':'egon','age':18}
for i in user_info.values():
    print(i)
>>>egon
>>>18

4.4 遍歷key和value
for i in user_info.items():
    print(i)
    
內建方法:
1、keys,values,items
dic= {'k1':'jason','k2':'Tony','k3':'JY'}
print(dic.keys())  #返回所有的key
print(dic.values()) #返回所有的value
print(dic.items()) #返回一個可迭代物件,是列表套元組的形式,每一個鍵值對都是一個元組
>>>dict_keys(['k1', 'k2', 'k3'])
>>>dict_values(['jason', 'Tony', 'JY'])
>>>dict_items([('k1', 'jason'), ('k2', 'Tony'), ('k3', 'JY')])


2、get():獲取指定key的值,如果值不存在,預設返回None,可以通過第二個引數修改預設返回的值
dic= {'k1':'jason','k2':'Tony','k3':'JY'}
dic.get('k1')
>>> 'jason'  
res=dic.get('xxx') # key不存在,不會報錯而是預設返回None
print(res)
>>> None  
res=dic.get('xxx',666) # key不存在時,可以設定預設返回的值
print(res)
>>> 666 
# ps:字典取值建議使用get方法

3、pop():刪除指定key對應的鍵值對,有返回值,返回為對應的value
dic= {'k1':'jason','k2':'Tony','k3':'JY'}
v =dic.pop('k2')  # 刪除指定的key對應的鍵值對,並返回值
print(dic)
>>> {'k1': 'jason', 'k3': 'JY'}
print(v)
>>> 'Tony'

4、popitem(): 隨機刪除一組鍵值對,並將刪除的鍵值放到元組內返回
dic= {'k1':'jason','k2':'Tony','k3':'JY'}
item = dic.popitem() 
print(dic)
>>> {'k3': 'JY', 'k2': 'Tony'}
print(item)
>>> ('k1', 'jason')
>
5、update():用新字典更新舊字典,有則修改,無則新增
dic= {'k1':'jason','k2':'Tony','k3':'JY'}
dic.update({'k1':'JN','k4':'xxx'})
print(dic)
>>>{'k1': 'JN', 'k3': 'JY', 'k2': 'Tony', 'k4': 'xxx'}

6、fromkeys():生成一個新字典,第一個引數(列表),它會以第一個引數中的各個元素為key,以第二個引數為值,組成一個新字典
dic = dict.fromkeys(['k1','k2','k3'],'egon')
print(dic)
>>>{'k1':'egon', 'k2':'egon', 'k3':'egon'}

7、setdefault():
若key不存在,新增鍵值對,有返回值,返回新增value。
dic={'k1':111,'k2':222}
res=dic.setdefault('k3',333)
print(res)
>>>333
print(dic) 
>>>{'k1': 111, 'k2': 222, 'k3': 333}

若key存在則不做任何修改,並返回已存在key對應的value值
dic={'k1':111,'k2':222}
res=dic.setdefault('k1',666)
res
>>> 111
dic # 字典不變
>>> {'k1': 111, 'k2': 222}

6.元組

元組就是一個不可變的列表
用途:儲存多個不同型別的值,只有讀的需求,沒有改的需求
定義方式:用小括號儲存資料,資料之間通過逗號分隔(值不能被改變)
t1 = ('a','b') # t1 = tuple(('a','b'))
強調:如果元組內只有一個值,則必須加一個逗號

常用方法:

1、按索引取值(正向取+反向取):只能取,不能改,否則報錯! 
tuple1 = (1, 'hhaha', 15000.00, 11, 22, 33)  
tuple1[0]
>>> 1
tuple1[-2]
>>> 22
tuple1[0] = 'hehe'  # 報錯:TypeError:

2、切片(顧頭不顧尾,步長)
tuple1[0:6:2]    
>>> (1, 15000.0, 22)   #切出來的還是元組

3、長度
len(tuple1)  
>>> 6

4、成員運算 innot in
tuple1 = (1, 'hhaha', 15000.00, 11, 22, 33)
print('hhaha' in tuple1)
print('hhaha' not in tuple1)

5、count()
tuple1 = (1, 'hhaha', 15000.00, 11, 22, 33)
print(tuple1.count(11))
>>>1
# 6、index()
tuple1 = (1, 'hhaha', 15000.00, 11, 22, 33)
print(tuple1.index('hhaha'))
>>>1

7.集合

用途:去重、關係運算
定義:在{ }內用逗號分隔開多個元素
1:每個元素必須是不可變型別
2:集合內沒有重複的元素
3:集合內元素是無序的
s = {1,2,3,4} # 本質 s = set({1,2,3,4})

注意1:列表型別是索引對應值,字典是key對應值,均可以取得單個指定的值,而集合型別既沒有索引也沒有key與值對應,所以無法取得單個的值,而且對於集合來說,主要用於去重與關係元素,根本沒有取出單個指定值這種需求。

注意2:{ }既可以用於定義dict,也可以用於定義集合,但是字典內的元素必須是key:value的格式,現在我們想定義一個空字典和空集合,該如何準確去定義兩者?

預設是空字典: d = {}    
定義空集合: s = set()
關係運算:

friends1 = {"zero","kevin","jason","egon"} # 使用者1的好友們 
friends2 = {"Jy","ricky","jason","egon"}   # 使用者2的好友們
1.合集(|):求兩個使用者所有的好友(重複好友只留一個)
>>> friends1 | friends2
{'kevin', 'ricky', 'zero', 'jason', 'Jy', 'egon'}

2.交集(&):求兩個使用者的共同好友
>>> friends1 & friends2
{'jason', 'egon'}

3.差集(-):
>>> friends1 - friends2 # 求使用者1獨有的好友
{'kevin', 'zero'}
>>> friends2 - friends1 # 求使用者2獨有的好友
{'ricky', 'Jy'}

4.對稱差集(^) # 求兩個使用者獨有的好友們(即去掉共有的好友)
>>> friends1 ^ friends2
{'kevin', 'zero', 'ricky', 'Jy'}

5.值是否相等(==)
>>> friends1 == friends2
False

6.父集:一個集合是否包含另外一個集合
6.1 包含則返回True
>>> {1,2,3} > {1,2}
True
>>> {1,2,3} >= {1,2}
True
6.2 不存在包含關係,則返回False
>>> {1,2,3} > {1,3,4,5}
False
>>> {1,2,3} >= {1,3,4,5}
False

7.子集
>>> {1,2} < {1,2,3}
True
>>> {1,2} <= {1,2,3}
True
去重:
集合去重複有侷限性:
  1. 只能針對不可變型別
  2. 集合本身是無序的,去重之後無法保留原來的順序
  
例如:
>>> l=['a','b',1,'a','a']
>>> s=set(l)
>>> s # 將列表轉成了集合
{'b', 'a', 1}
>>> l_new=list(s) # 再將集合轉回列表
>>> l_new
['b', 'a', 1] # 去除了重複,但是打亂了順序

# 針對可變型別,並且保證順序則需要我們自己寫程式碼實現,例如       這裡的0,3,4的記憶體id並不相同
l=[
    {'name':'lili','age':18,'sex':'male'},
    {'name':'jack','age':73,'sex':'male'},
    {'name':'tom','age':20,'sex':'female'},
    {'name':'lili','age':18,'sex':'male'},
    {'name':'lili','age':18,'sex':'male'},
]

new_l=[]

for i in l:
    if i not in new_l:
        new_l.append(i)

print(new_l)
# 結果:既去除了重複,又保證了順序,而且是針對不可變型別的去重
#列印結果:
[
    {'age': 18, 'sex': 'male', 'name': 'lili'}, 
    {'age': 73, 'sex': 'male', 'name': 'jack'}, 
    {'age': 20, 'sex': 'female', 'name': 'tom'}
]

8.布林型別(True,False)

用途:判斷

重點:所有資料型別自帶布林值,等號比較的是值,is比較的是地址

0,
None,
空:"",[],{}的值為False
其餘全部為真

七、可變型別與不可變型別

可變:值改變的情況下,id不變
不可變:值一變,id就變

不可變型別:數字,字串,元組
可變型別:列表,字典,集合

x =1
print(id(x),x)
x =2
print(id(x),x)
# >>>140736221442320 1
# >>>140736221442352 2
#
x="abc"
print(id(x),x)
x="bcd"
print(id(x),x)
# >>>2291351178288 abc
# >>>2291351217840 bcd

x=['a','b','c']
print(id(x),type(x),x)
x[2]=10
print(x)
print(id(x),type(x),x)
# >>>1887760765512 <class 'list'> ['a', 'b', 'c']
# >>>['a', 'b', 10]
# >>>1887760765512 <class 'list'> ['a', 'b', 10]

dic={'x':1,'y':2}
print(id(dic),type(dic),dic)
dic['x']=111111111
print(dic)
print(id(dic),type(dic),dic)
# >>>1571299274008 <class 'dict'> {'x': 1, 'y': 2}
# >>>{'x': 111111111, 'y': 2}
# >>>1571299274008 <class 'dict'> {'x': 111111111, 'y': 2}

八、基本運算子

1.算數運算子

//:取整
%:取餘數
**:次冪

2.比較運算子

!= 不等於

3.賦值運算子

1)增量賦值: +=  //= %= 等等
2)鏈式賦值: x = y = z = 1
3)交叉賦值:m = 10 ,n = 20
           m,n=n,m
4)解壓賦值:
  l1=[1,2,3,4]
  a,b,c,d=l1
  print(a,b,c,d)
  >>>(1,2,3,4)
  
l1 =[1,2,3,4]
a,b,*_=l1
print(a,b)
>>>(1,2)

4.邏輯運算

與 或 非
and or not
邏輯運算子的優先順序順序:notandor


a = 1
b = 2
c = 3
print(a < b and b > c)  # and:如果有一個式子不符合條件,整條式子都為False
print(a > b and b < c)
print(a < b or b < c)   # or:只要有一個式子符合條件,整條式子都為True
print(a > b or b < c)
print(not a < b)  # 取反
print(a < b and b < c or a > c)  # True
print(a > b or b < c and a > c)  # False

九:進位制轉換

十進位制轉成其他進位制
bin(3): ob11         #十進位制轉二進位制
oct(8): oc10         #十進位制轉八進位制
hex(16) ox10         #十進位制轉十六進位制

其他進位制轉換成十進位制

二進位制轉成十進位制
print(int('110',2)) #第二個引數是第一個引數的進位制

八進位制轉成十進位制
print(int('110',8))