Python List Repeating Last Element For Whole List

荒凉一梦 提交于 2019-12-13 19:22:55

问题


I am writing a python program just to make a simple poker game. I just want to become familiar with the Python language. I know my method of writing the python code isn't exactly Pythonic but really I'm just trying to figure out why my list is appending the last object repeatedly to each space in the List. As I am appending, the list has the correct values but after it just appends the last object repeatedly. I've spent about two days trying to figure it out and I'm sure it's just something I'm overlooking with the language. Any help would be appreciated. Here is the code:

class Card(object):
    suit = ""
    value = ""

    def __init__(self, suit, value):
        Card.suit=suit
        Card.value=value

def createDeck():

    suit = ["DIAMONDS", "HEARTS", "CLUBS","SPADES"]
    value = ["ACE", "TWO", "THREE", "FOUR", "FIVE", 
         "SIX", "SEVEN", "EIGHT", "NINE", "TEN", 
         "JACK", "QUEEN", "KING"]
    Deck = []

    for i in range(4):
        for j in range(13):
            card = Card(suit[i],value[j])
            Deck.append(card)
            print(Deck[i].value, "OF", Deck[i].suit)

    displayDeck(Deck)

def displayDeck(Deck = [], *args):
    for i in range(len(Deck)):
        print(Deck[i].value, " OF ", Deck[i].suit)

This is the Output I get, it's shortened for brevity: C:\Users\root\Desktop>py Poker.py

ACE OF DIAMONDS

-All Cards Through-

KING OF SPADES

KING OF SPADES

KING OF SPADES

KING OF SPADES

KING OF SPADES
etc. Until The list is filled (52 spots)

回答1:


In your Card.__init__-method you set class attributes instead if instance attributes. So every Card instance has the same attributes, the last one set (King Of Spades). So, set instance attributes with self.:

class Card(object):
    def __init__(self, suit, value):
        self.suit = suit
        self.value = value

So one usage of class attributes would be the constants of suit and value names:

class Card(object):
    SUITS = ["DIAMONDS", "HEARTS", "CLUBS","SPADES"]
    VALUES = ["ACE", "TWO", "THREE", "FOUR", "FIVE", 
        "SIX", "SEVEN", "EIGHT", "NINE", "TEN", 
        "JACK", "QUEEN", "KING"]

    def __init__(self, suit, value):
        self.suit = suit
        self.value = value

def create_deck():
    deck = []
    for suit in Card.SUITS:
        for value in Card.VALUES:
            card = Card(suit,value)
            deck.append(card)
            print(card.value, "OF", card.suit)
    return deck

def display_deck(deck):
    for card in deck:
        print(card.value, " OF ", card.suit)

deck = create_deck()
display_deck(deck)



回答2:


Try it like this

    def __init__(self, suit, value):
       self.suit=suit
       self.value=value

This is how you properly set suit and value to Card object.

for i in range(4):
    for j in range(13):
        card = Card(suit[i],value[j])
        Deck.append(card)
displayDeck(Deck)  

I deleted the print statement inside the loops. Now the output is:

('ACE', ' OF ', 'DIAMONDS')
('TWO', ' OF ', 'DIAMONDS')
('THREE', ' OF ', 'DIAMONDS')
('FOUR', ' OF ', 'DIAMONDS')
('FIVE', ' OF ', 'DIAMONDS')
('SIX', ' OF ', 'DIAMONDS')
('SEVEN', ' OF ', 'DIAMONDS')
('EIGHT', ' OF ', 'DIAMONDS')
('NINE', ' OF ', 'DIAMONDS')
('TEN', ' OF ', 'DIAMONDS')
('JACK', ' OF ', 'DIAMONDS')
('QUEEN', ' OF ', 'DIAMONDS')
('KING', ' OF ', 'DIAMONDS')
('ACE', ' OF ', 'HEARTS')
('TWO', ' OF ', 'HEARTS')
('THREE', ' OF ', 'HEARTS')
('FOUR', ' OF ', 'HEARTS')
('FIVE', ' OF ', 'HEARTS')
('SIX', ' OF ', 'HEARTS')
('SEVEN', ' OF ', 'HEARTS')
('EIGHT', ' OF ', 'HEARTS')
('NINE', ' OF ', 'HEARTS')
('TEN', ' OF ', 'HEARTS')
('JACK', ' OF ', 'HEARTS')
('QUEEN', ' OF ', 'HEARTS')
('KING', ' OF ', 'HEARTS')
('ACE', ' OF ', 'CLUBS')
('TWO', ' OF ', 'CLUBS')
('THREE', ' OF ', 'CLUBS')
('FOUR', ' OF ', 'CLUBS')
('FIVE', ' OF ', 'CLUBS')
('SIX', ' OF ', 'CLUBS')
('SEVEN', ' OF ', 'CLUBS')
('EIGHT', ' OF ', 'CLUBS')
('NINE', ' OF ', 'CLUBS')
('TEN', ' OF ', 'CLUBS')
('JACK', ' OF ', 'CLUBS')
('QUEEN', ' OF ', 'CLUBS')
('KING', ' OF ', 'CLUBS')
('ACE', ' OF ', 'SPADES')
('TWO', ' OF ', 'SPADES')
('THREE', ' OF ', 'SPADES')
('FOUR', ' OF ', 'SPADES')
('FIVE', ' OF ', 'SPADES')
('SIX', ' OF ', 'SPADES')
('SEVEN', ' OF ', 'SPADES')
('EIGHT', ' OF ', 'SPADES')
('NINE', ' OF ', 'SPADES')
('TEN', ' OF ', 'SPADES')
('JACK', ' OF ', 'SPADES')
('QUEEN', ' OF ', 'SPADES')
('KING', ' OF ', 'SPADES')
[Finished in 0.3s]



回答3:


To elaborate Rockybilly's answer, your Card class is defining two class attributes, suit and value. Every instance of your Card class shares these two values, meaning if you change it in one instance, it is changed in all instances. That's what's happening currently in your Card.__init__ method when you do something like Card.suit = suit. You're modifying the suit for all Cards you've ever created. In your case, the King of Spades is the last card you create, so its suit and value is the one that gets set for all 52 cards you've created.

What you want to do is treat suit and value as instance values, meaning you refer to them within your class via self. Furthermore, you don't need to set their values at the class level (i.e., right below the class Card line). Instead, you just initialize them within your __init__ method. Try changing your Card class to this:

class Card( object ):
    def __init__( self, suit, value ):
        self.suit = suit
        self.value = value



回答4:


First of all, you can fix your Card class like this:

class Card(object):
    def __init__(self, suit = None, value = None):
        self.suit=suit
        self.value=value

This will solve your problem of the last card being displayed a bunch of times, because you are no longer constantly modifying the same Card object. But after that fix, you would have run into another problem because of your print statment. It's because on each loop of j, you are using the ith card in the deck, but i has not been incrememnted until j has increased by 13. This would have been better:

current = 0
for i in range(4):
    for j in range(13):
        card = Card(suit[i],value[j])
        Deck.append(card)
        print(Deck[current].value, "OF", Deck[current].suit)
        current = += 1

But obviously is messy. You want:

for i in range(4):
    for j in range(13):
        card = Card(suit[i],value[j])
        Deck.append(card)
display_deck(Deck)


来源:https://stackoverflow.com/questions/34440235/python-list-repeating-last-element-for-whole-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!