我有一个52个元组(一副扑克牌)的列表,我试图在不使用random.shuffle的情况下进行混洗(不允许在该项目中使用它)。我想做的是创建2个随机索引,从列表中删除这些项目,然后在列表的最前面放置1个,在列表的末尾放置1个。
我可以创建随机#,但不确定如何移动它们。似乎.pop是我最好的方法,但不确定是否正确。
def shuffle():
ite = 0
while ite <= 1000:
rand1 = randint(0, len(card_deck) -1)
rand2 = randint(0, len(card_deck) -1)
card_deck.pop[rand1]
card_deck.append(rand1)
ite += 1
shuffle()
答案 0 :(得分:2)
在这种情况下,Pop的时间复杂度并不理想。将rand1的值存储为临时变量并将其替换为rand2的值,然后将rand2的值替换为临时变量会更有意义。而且,如下面的注释所述,效率更高,您可以交换两个值而无需使用临时变量。
例如,如果您有1000个项目的列表,并且想要弹出第500个项目,则它将在N(500)时间内运行。而您可以在固定时间内访问列表中的项目。
如果您是在做家庭作业,请尝试在未亲自执行的情况下查看下面的答案。
def shuffle():
ite = 0
while ite <= 1000:
rand1 = randint(0, len(card_deck) - 1)
rand2 = randint(0, len(card_deck) - 1)
card_deck[rand1], card_deck[rand2] = card_deck[rand2], card_deck[rand1]
ite += 1
答案 1 :(得分:0)
正如@Sean Payne指出的那样; pop()
并非可行之路。当您只想在值周围交换时,pop()
会非常慢。 Python允许(鼓励)元组分配,因此人们可以在不使用临时存储位置x, y = y, x
或在这种情况下为deck[i], deck[j] = deck[j], deck[i]
的情况下交换值。
for
循环比while
循环更具蟒蛇性。
我猜想您的老师正在设法让您编写适当的Knuth混洗(link),也称为Fisher-Yates或Fisher-Yates-Knuth。 Durstenfeld是该算法的另一个重要贡献者。
import random
def shuffle(deck):
for i in range(len(deck)-1, 0, -1):
j = random.randint(0,i)
deck[i], deck[j] = deck[j], deck[i]
return deck
mydeck = list(range(52))
print(mydeck)
print(shuffle(mydeck))
要注意的最大区别是,一旦选择了要处理的项目到列表的末尾,就将其保留在那里。如果您继续生成数字,以允许对已经洗牌的项目进行重新洗牌,那么实际上会降低洗牌的随机性。 Mike Bostock和Jeff Atwood对这个问题都有很好的解释。
如果您真的想要前后移动,可以执行类似的操作
import random
def shuffle2(deck):
back_of_deck = len(deck) - 1
for i in range(len(deck)//2):
front = random.randint(i,back_of_deck)
back = random.randint(i,back_of_deck)
deck[i], deck[front] = deck[front], deck[i]
deck[back_of_deck], deck[back] = deck[back], deck[back_of_deck]
back_of_deck -= 1
return deck
mydeck = list(range(52))
print(mydeck)
print(shuffle2(mydeck))
答案 2 :(得分:0)
我认为这就是您要寻找的
import random
def build_deck():
'''
build a fresh sorted deck of cards
'''
nums = range(1,14)
types = ['Heart','Spade','Club','Diamond']
deck = [(x,y) for x in types for y in nums]
return deck
def get_random_indices(from_=1,to=50):
'''
get 2 random indices to choose from which are not similar
'''
index1 = random.randint(from_,to)
index2 = random.randint(from_,to)
if index1 == index2:
index1,index2 = get_random_indices(from_,to)
return index1,index2
def shuffle_deck(deck,n_times=52):
'''
shuffle deck n times
'''
if n_times>0:
index1,index2 = get_random_indices()
card1 = deck.pop(index1)
card2 = deck.pop(index2)
deck.append(card1)
deck.insert(0,card2)
n_times-=1
shuffle_deck(deck,n_times=n_times)
return deck
deck = build_deck()
new_deck = shuffle_deck(deck,52)
new_deck
您可以通过使用random.choice()
选择是插入还是附加card1来增加随机性。