昨天,我决定第一次开始使用Python,所以请放轻松,我几乎没有编程经验。 作为我的第一个小项目,我正在尝试制作一个脚本,对牌组进行洗牌,并从洗牌后发出5张牌。 我正在尝试将手存储在二维数组/矩阵中。 这是我遇到的代码:
var styleWithoutAttr = styleTags.replace("type=['\"]text/css['\"]", '')
我的import random
sorted_deck = ["AH","KH","QH","JH","TH","9H","8H","7H","6H","5H","4H","3H","2H",
"AS","KS","QS","JS","TS","9S","8S","7S","6S","5S","4S","3S","2S",
"AD","KD","QD","JD","TD","9D","8D","7D","6D","5D","4D","3D","2D",
"AC","KC","QC","JC","TC","9C","8C","7C","6C","5C","4C","3C","2C"]
def shuffle():
sorted_deck_current = list()
sorted_deck_current.clear()
sorted_deck_current = sorted_deck.copy()
shuffled_deck = list()
shuffled_deck.clear()
for n in range(0,52):
r = random.randrange( 0, len(sorted_deck_current) )
shuffled_deck.append( sorted_deck_current[r] )
sorted_deck_current.pop( r )
return shuffled_deck
for n in range(2): # Check that the shuffle()-function works
fresh_shuffled = shuffle()
print( "Shuffled deck: " + str(fresh_shuffled) )
many_hands = list()
temp_hand = list()
temp_deck = list()
many_hands.clear()
for n in range(5): # Draw 5 hands from freshly shuffled decks
temp_hand.clear()
temp_deck.clear()
temp_deck = shuffle()
for i in range(5):
temp_hand.append( temp_deck[i] )
many_hands.append( temp_hand )
print( many_hands[n] )
for q in range(5): # Try and output the 5 different hands again
print( many_hands[q] )
exit()
循环在代码末尾输出5张不同的牌,这就是我想要的。
for n in range(5)
循环输出同一手牌5次,恰好是前一个循环的最后一手牌。
我不知道为什么会这样。
如果有人可以向我解释这种行为,将不胜感激。
答案 0 :(得分:2)
您正在创建temp_hand
,然后再开始第一个for
循环。之后,您总是总是修改同一对象,然后将其重新添加到many_hands
。本质上,您只是将同一对象添加了五次。如果您熟悉C,那就像传递引用:python在追加列表之前不复制列表的值,它只是将引用添加到列表。
因此,稍后,当您尝试打印many_hands
时,它将打印同一对象5次。
此问题的解决方案是在temp_hand
循环内而不是外部初始化for
内部,以便每次迭代都将其初始化(作为新参考) 。也就是说,替换行
temp_hand.clear()
使用
修改您当前拥有的单个列表,而不更改其引用temp_hand = list()
,它将在新引用处创建一个新的空列表,并将其分配给temp_hand
。
顺便说一句,初始化空列表时,通常首选使用列表文字(即[]
)而不是list()
构造函数。这主要是因为它从其周围的代码中脱颖而出,它肯定是一个列表,而不是恰好返回一个列表的函数调用。
答案 1 :(得分:1)
首先修复,在每次迭代时创建一个新的列表对象:
for draw in range(5): # try avoid single letter variables
temp_hand = [] # Make a NEW list object. BTW, [] is nicer and more common syntax than list()
temp_deck = shuffle()
temp_hand = temp_deck[:5] # Use slicing to get the first 5 elements, not a loop!
many_hands.append(temp_hand) # This will get a different list object appended each time which is what you want.
那出了什么问题?在python中,当您将列表分配给变量时,您不会分配列表的副本,而是对其的引用。尝试以下代码:
list1 = [1, 2, 3] # Make a new list object
list2 = list1 # Assigns a reference to the existing list1
list1[0] = 9
print(list2)
您将看到list2
已更改。这是因为list1
和list2
指向同一个对象。您可以使用is
或id
在python中进行检查:
print(f"list1 id: {id(list1)}")
print(f"list2 id: {id(list2)}")
它们是相同的。另外,list1 is list2
返回True
。
但是现在尝试一下:
list1 = [1, 2, 3]
list2 = [1, 2, 3]
现在list1 == list2
是True
,但是list1 is list2
是False
。它们是单独的对象。
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list1[0] = 9
print(list2)
这次list2
尚未更改。
在原始代码中,您通过调用temp_hand
来保持对.append()
的引用,而不是在每次迭代中创建一个新的列表对象。因此,在每个循环中,您都洗牌temp_hand
并打印,然后看到新手。但是,您未查看的是many_hands
中已经发生的值发生了什么。这些都指向同一个对象,因此它们 all 都在每次迭代中进行更改。
这是证明这一点的另一种方式:
list1 = []
for _ in range(5):
list1.clear()
list1.append(1) # It is really your use of append that is the culprit as this is where you EDIT an existing list instead of ASSIGNING a new one
list2 = [1]
print(f"list1 id: {id(list1)}, list2 id: {id(list2)}")
看看list1
总是一样,但是list2
每次都改变吗?
一开始我的代码可以更短,但是我想说明使用[]
创建列表,但是实际上shuffle
本身会创建一个新列表,因此您可以这样做:
for draw in range(5): # try avoid single letter variables
temp_hand = shuffle()[:5]
many_hands.append(temp_hand)
答案 2 :(得分:0)
您无需为每只手创建新列表,而是为每只手清空并填充temp_hand
,这样many_hands
便是该同一列表/手的5个引用的列表。
如果您执行temp_hand.clear()
而不是temp_hand = list()
(将其设为新的空白列表),则应该获得期望的结果。