COMP9021 Principles of Programming WEEK4

1. deque()

deque雖然使用時(shí)很像list,但是兩者截然不同滑负。deque是一個(gè)doubly linked list而list是一個(gè)array骡技,所以處理兩端數(shù)據(jù)的時(shí)候deque的復(fù)雜度是O(1),而list是O(n)凹耙。但deque處理中部數(shù)據(jù)的效率低稀轨,是O(n)扼脐。因此,當(dāng)處理隨機(jī)狀態(tài)時(shí)奋刽,使用list更好瓦侮。

from collections import deque
D = deque()
D.append(5)
print(D)
print(D.popleft())
print(D)

D.append(6)
print(D[0])
print(D)
>>>
deque([5])
5
deque([])
6
deque([6])

2. Card Shuffling Simulator

洗牌的流程是先將一副牌分成盡量均勻的A和B兩部分,之后選擇A或者B的第一張作為洗牌之后的第一張佣谐,然后A和B各自的順序保持不變肚吏,但是彼此交叉在一起形成新順序。A和B未洗的牌越多狭魂,就越容易被優(yōu)先選中罚攀。

2.1 將牌分成兩部分

為了保證盡量均勻,每張牌用擲篩子的方式(randint(0, 1))選擇分到哪一部分雌澄。

from random import randint

nb_of_heads = 0
for _ in range(52):
#總共52張牌斋泄,沒有大小王
    outcome = randint(0, 1)
    if outcome == 1:
        nb_of_heads += 1

print(nb_of_heads)

簡(jiǎn)化后的寫法

from random import randint

sum(randint(0, 1) for _ in range(52))

2.2 洗牌

根據(jù)分成兩個(gè)部分的牌數(shù)量將牌切成兩部分,記錄數(shù)量為i2(第二部分牌開始的index)镐牺,第一部分牌開始的index為i1(初始值為0)炫掐,洗后的牌index為i(初始值為0),剩余未洗卡牌數(shù)量為nb_of_cards_left(初始值為52)睬涧。
在洗牌過程中會(huì)出現(xiàn)一部分的牌全部洗完的狀況募胃,這時(shí)講剩余部分的牌直接放入洗過的牌的后邊。

deck = list(range(52))
cut = sum(randint(0, 1) for _ in range(52))

new_deck = [None] * 52
i1 = 0
i2 = cut 
i = 0
nb_of_cards_left = 52

while i1 < cut and i2 < 52:
    if randint(0, nb_of_cards_left - 1) < cut - i1:
    #rand(0, nb_of_cards_left - 1) 能夠根據(jù)兩部分剩余厚度等概率選擇下一張洗的牌
        new_deck[i] = deck[i1]
        i1 += 1
    else:
        new_deck[i] = deck[i2]
        i2 += 1
    i += 1
    nb_of_cards_left -= 1
    
if i1 == cut:
    new_deck[i: ] = deck[i2: ]
else:
    new_deck[i: ] = deck[i1: cut]
print(new_deck)

3. Identity

首先明確概念畦浓,計(jì)算機(jī)程序中的各種數(shù)字并不是真正的值痹束。比如3,3.14讶请,這些數(shù)實(shí)際上由兩部分構(gòu)成:一部分是name--"3", "3,14"祷嘶,另一部分是storage,存儲(chǔ)的binary bits秽梅。這兩個(gè)部分分別叫做v-name和v-storage抹蚀,計(jì)算機(jī)中并不存在值這個(gè)概念,它是一個(gè)抽象概念企垦,大體可以理解為v-name指向v-storage。
v-name可以出現(xiàn)多次晒来,比如可以有N個(gè)"2"作為v-name钞诡,2 + 2中,v-name2出現(xiàn)了兩次。在v-name中有兩種形式荧降,constant expressions和variable expressions接箫。
constant expression:例如2和1+1。如下面程序所示朵诫,2和1+1都指向相同的binary bits辛友。所以,1+1的過程實(shí)際上是先做運(yùn)算1+1剪返,根據(jù)值2的v-storage再分配一個(gè)v-name废累。等號(hào)實(shí)際上是把v-name指向了v-storage,所以下面程序x=2的時(shí)候是把2所在的v-storage再加上一個(gè)新的v-name x脱盲。

>>> id(2)
4297636928
>>> id(1 + 1)
4297636928
>>> x = 2
>>> id(x)
4297636928

對(duì)于基礎(chǔ)類型邑滨,都和上述的int類型一致,例如下面列舉的bool類型和str類型钱反。

>>> id(False)
4297244992
>>> a = False
>>> id(a)
4297244992
>>> b = False
>>> id(b)
4297244992

>>> id('abc')
4314648336
>>> a = 'abc'
>>> id(a)
4314648336
>>> b = 'abc'
>>> id(b)
4314648336

對(duì)于非基礎(chǔ)類型掖看,比如List, tuple, set, dictionary,要根據(jù)實(shí)際情況分析面哥。比如由于list可修改哎壳,所以他的分配都是動(dòng)態(tài)的,x = [2]和y = [2]兩者的存儲(chǔ)位置不同尚卫;而tuple是不可修改的耳峦,所以他的分配是靜態(tài)的,x = (2)和y = (2)兩者的存儲(chǔ)位置相同焕毫;set和dictionary是經(jīng)過hash的蹲坷,所以不僅x = {2}和y = {2}不同,他們也都和{2}不同邑飒。

>>> id([2])
4316726600
>>> x = [2]
>>> id(x)
4316726600
>>> y = [2]
>>> id(y)
4316726664

>>> id((2))
4297636928
>>> x = (2)
>>> id(x)
4297636928
>>> y = (2)
>>> id(y)
4297636928

>>> id({2})
4316700456
>>> x = {2}
>>> id(x)
4316700232
>>> y = {2}
>>> id(y)
4316700456

is的判斷是判別v-storage地址是否一樣循签,而==的判別是判斷v-storage的binary bits是否一樣。
由于binary是8位的疙咸,2^8 =256县匠,所以如果一個(gè)數(shù)大于256,v-storage的地址會(huì)變化撒轮,小于的時(shí)候不變化乞旦,這樣用上文說的is判斷就會(huì)出現(xiàn)下述情況

>>> x = 257
>>> x is 257
False
>>> x = 256
>>> x is 256
True

programming的時(shí)候如果遇到可修改的非基礎(chǔ)類型數(shù)據(jù),一定要小心generate的方式题山。如下:

>>> X = [0] * 3; X
[0, 0, 0]
>>> id(X), id(X[0]), id(X[1]), id(X[2])
(4521957128, 4481604640, 4481604640, 4481604640)
>>> X[0] = 1; X
[1, 0, 0]
>>> id(X), id(X[0]), id(X[1]), id(X[2])
(4521957128, 4481604672, 4481604640, 4481604640)

[0] * 3兰粉,由于0是基本數(shù)據(jù)類型,實(shí)際上產(chǎn)生3次0顶瞳,地址改變玖姑,所以如果對(duì)其中任何一個(gè)進(jìn)行修改愕秫,三者不會(huì)全部變化。

>>> X = [[0]] * 3; X
[[0], [0], [0]]
>>> id(X), id(X[0]), id(X[1]), id(X[2])
(4521981960, 4511587784, 4511587784, 4511587784)
>>> X[0][0] = 1; X
[[1], [1], [1]]
>>> id(X), id(X[0]), id(X[1]), id(X[2])
(4521981960, 4511587784, 4511587784, 4511587784)

[[0]] * 3焰络,由于[0]是可修改的非基礎(chǔ)數(shù)據(jù)類型戴甩,實(shí)際上并沒有產(chǎn)生3次[0],而是給了3個(gè)v-name而已闪彼,地址未變甜孤,所以如果對(duì)其中任何一個(gè)進(jìn)行修改,三者全部變化畏腕。如果想要產(chǎn)生3個(gè)[0]缴川,用下面的方法。

>>> X = [[0] for i in range(3)]; X
[[0], [0], [0]]
>>> id(X), id(X[0]), id(X[1]), id(X[2])
(4521980424, 4521980104, 4521981832, 4521980680)
>>> X[0][0] = 1; X
[[1], [0], [0]]
>>> id(X), id(X[0]), id(X[1]), id(X[2])
(4521980424, 4521980104, 4521981832, 4521980680)

4. Game of Life

游戲規(guī)則:A cell comes into existence at an empty spot when that spot is surrounded by exactly 3 cells. A cell survives if and only if it is surrounded by exactly 2 or 3 cells.

4.1 顯示數(shù)據(jù)

0代表死郊尝,1代表生二跋,有以下兩種方法顯示數(shù)據(jù)。

Method 1:
def print_grid():
    for i in range(20):
        for j in range(20):
            print(grid[i][j], end = ' ')
        print()

grid = [[0] * 20] * 20

Method 2:
def print_grid():
    for i in range(20):
        print(' '.join(str(e) for e in grid[i]))

grid = [[0] * 20] * 20

注意流昏,這里生成grid用到grid = [[0] * 20] * 20是沒有問題的扎即,因?yàn)閇0]中的0是基礎(chǔ)數(shù)據(jù)類型int。如果改成grid = [[[0]] * 20] * 20則會(huì)出問題况凉,因?yàn)閇[0]]中的[0]是非基礎(chǔ)數(shù)據(jù)類型list且可修改谚鄙。如果grid = [[(0)] * 20] * 20則不會(huì)出問題,因?yàn)閇(0)]]中的(0)是非基礎(chǔ)數(shù)據(jù)類型tuple刁绒,但不可修改闷营。

4.2 生成生死規(guī)則

注意全局變量使用和bondary的巧妙處理方式(在原數(shù)據(jù)外層加一圈符合規(guī)則的數(shù)據(jù))

from random import randrange

dim = 20

def print_grid():
    for i in range(1, dim + 1):
        print(' '.join(str(e) for e in grid[i]))

def initialise_grid():
    for i in range(1, dim + 1):
        for j in range(1, dim + 1):
            if not randrange(0, density):
                grid[i][j] = 1

def update_grid():
    global grid
    #因?yàn)樽詈骻rid =,賦值了知市,grid是local傻盟;如果只是改變grid的值,那么不用global
    for i in range(1, dim + 1):
        for j in range(1, dim + 1):
            nb_of_neighbours = sum((grid[i - 1][j - 1], grid[i - 1][j], grid[i - 1][j + 1],
                                  grid[i][j - 1], grid[i][j + 1],
                                  grid[i + 1][j - 1], grid[i + 1][j], grid[i + 1][j + 1]))
            if grid[i][j] and nb_of_neighbours in {2, 3} or\
                    not grid[i][j] and nb_of_neighbours == 3:
                new_grid[i][j] = 1
    grid = new_grid
    
density = 2
grid = [[0] * (dim + 2) for _ in range(dim + 2)]
initialise_grid()
print_grid()
print()

update_grid()
print_grid()
new_grid = [[0] * (dim + 2) for _ in range(dim + 2)]
#周圍加一圈0嫂丙,方便check周圍多少neighbor是1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娘赴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子跟啤,更是在濱河造成了極大的恐慌诽表,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隅肥,死亡現(xiàn)場(chǎng)離奇詭異竿奏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)腥放,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門泛啸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人捉片,你說我怎么就攤上這事平痰」眨” “怎么了伍纫?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵宗雇,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我莹规,道長(zhǎng)赔蒲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任良漱,我火速辦了婚禮舞虱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘母市。我一直安慰自己矾兜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布患久。 她就那樣靜靜地躺著椅寺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蒋失。 梳的紋絲不亂的頭發(fā)上返帕,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音篙挽,去河邊找鬼荆萤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛铣卡,可吹牛的內(nèi)容都是我干的链韭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼煮落,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼敞峭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起州邢,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤儡陨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后量淌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骗村,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年呀枢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胚股。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裙秋,死狀恐怖琅拌,靈堂內(nèi)的尸體忽然破棺而出缨伊,到底是詐尸還是另有隱情,我是刑警寧澤进宝,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布刻坊,位于F島的核電站,受9級(jí)特大地震影響党晋,放射性物質(zhì)發(fā)生泄漏谭胚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一未玻、第九天 我趴在偏房一處隱蔽的房頂上張望灾而。 院中可真熱鬧,春花似錦扳剿、人聲如沸旁趟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锡搜。三九已至,卻和暖如春敛劝,著一層夾襖步出監(jiān)牢的瞬間余爆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工夸盟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛾方,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓上陕,卻偏偏與公主長(zhǎng)得像桩砰,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子释簿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容