Danger Cat
Danger Cat

Reputation: 39

Taking things out of one list and putting them in another (python)

I'm working some code for my second ever assignment, a Go Fish game in python. For one of my function definitions, I need to take out the target_rank out of the target_player list of cards, and append it to the current players card list. I have tried using for loops, but receive errors for changing the length of the list. So far the code I have is

def Hit(player_number, target_player, target_rank, pHands):
    while str(target_rank) in pHands[target_player]:
       pHands[player_number].append(pHands[target_player].pop(target_rank))
    print pHands[player_number]
    print pHands[target_player]
pHands = [['a', '2', '3', '4', '4', '5', '6', '7', '7', 't'], ['2', 'q', '6', '9', '5', 'k', 'k', 'a', '3', '8'], ['j', '9', 't', 't', '2', 't', '7', 'j', '5', '9'], ['8', '8', 'a', 'q', 'k', '4', '6', '9', 'q', '2']]
Hit (0,1,'a',pHands)

Where pHands is a list of lists of the players card. I understand I can't use pop since target rank is a string and not the place value, but any help would be much appreciated. Thanks everyone!

Upvotes: 0

Views: 172

Answers (2)

unutbu
unutbu

Reputation: 881037

I think it might be clearer not to chain the pop with the append. Moreover, pop requires an index number, not the card value itself, so it is a little awkward to use here. Instead, you could use remove:

def Hit(player_number, target_player, target_rank, pHands):
    while target_rank in pHands[target_player]:
        pHands[target_player].remove(target_rank)
        pHands[player_number].append(target_rank)
    print pHands[player_number]
    print pHands[target_player]

However, pop and remove are O(n) operations. Doing that once for every card in pHands[target_player] makes the while-loop O(n**2). It would be better if we could perform the task in O(n), and that is possible with append, which is an O(1) operation. So if all we need to do is append once for each card in pHands[target_player], then the for-loop (below) is O(n):

def Hit(player_number, target_player, target_rank, pHands):
    new_target_hand = []
    for card in pHands[target_player]:
        if target_rank == card:
            pHands[player_number].append(card)
        else:
            new_target_hand.append(card)
    pHands[target_player] = new_target_hand
    print pHands[player_number]
    print pHands[target_player]

Upvotes: 3

smakateer
smakateer

Reputation: 556

EDIT: Mine works but THIS one is cleaner.

def Hit(player_number, target_player, target_rank, pHands):
    try:
        while True:
           pHands[player_number].append(pHands[target_player].pop(pHands.index(target_rank)))
        print pHands[player_number]
        print pHands[target_player]
    except ValueError:
        pass # value no longer in hand
pHands = [['a', '2', '3', '4', '4', '5', '6', '7', '7', 't'], ['2', 'q', '6', '9', '5', 'k', 'k', 'a', '3', '8'], ['j', '9', 't', 't', '2', 't', '7', 'j', '5', '9'], ['8', '8', 'a', 'q', 'k', '4', '6', '9', 'q', '2']]
Hit (0,1,'a',pHands)

Upvotes: 1

Related Questions