如何从列表中删除项目并将其添加到同一列表的末尾

how do i remove an item from a list and add it to the end of the same list

我有一个包含 52 个元组(一副扑克牌)的列表,我试图在不使用 random.shuffle 的情况下洗牌(不允许将其用于此项目)。我想要做的是创建 2 个随机索引,从列表中删除这些项目,并将 1 个放在列表的前面,将 1 个放在列表的末尾。

我可以创建随机 #'s,但不确定如何移动它们。 .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()

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

正如@Sean Payne 指出的那样; pop() 不是要走的路。 pop()当您只想交换值时,速度非常慢。 Python 允许(鼓励)元组分配,因此可以在不使用临时存储位置 x, y = y, x 的情况下交换值,或者在这种情况下 deck[i], deck[j] = deck[j], deck[i].

for 循环比 while 循环更 pythonic。

我猜你的老师正试图让你写一个正确的 Knuth shuffle (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))

Try it online!

需要注意的最大区别是,一旦您选择了哪个项目进入您正在使用的列表的末尾,就将其留在那里。如果您继续生成允许重新洗牌的项目的数字,它实际上会降低洗牌的随机性。 Mike Bostock and 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))

Try it online!

我想这就是您要找的

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 来增加额外的随机性