Python - How to use a list comprehension to populate the values ββof named tuples
I have the following class that creates a deck of cards:
import collections
Card = collections.namedtuple('Card', ['rank', 'suit', 'value'])
class FrenchDeck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades clubs hearts diamonds'.split()
card_value = [str(n + 1) for n in range(len(ranks))]
def __init__(self):
self._cards = [Card(rank, suit, value)
for suit in self.suits
for rank in self.ranks
for value in self.card_value
]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
if __name__ == '__main__':
FrenchDeck()
I added a value value
to the Map to assign a value to each map, for example:
Card(rank='2', suit='spades', value='1')
Card(rank='2', suit='spades', value='2')
Card(rank='2', suit='spades', value='3')
Card(rank='2', suit='spades', value='4')
Card(rank='2', suit='spades', value='5')
Card(rank='2', suit='spades', value='6')
Card(rank='2', suit='spades', value='7')
Card(rank='2', suit='spades', value='8')
Card(rank='2', suit='spades', value='9')
Card(rank='2', suit='spades', value='10')
Card(rank='2', suit='spades', value='11')
Card(rank='2', suit='spades', value='12')
Card(rank='2', suit='spades', value='13')
He creates 13 items for each rank for each suit. I understand why this is happening, but I am struggling, adding value to each rank in a suit like this:
Card(rank='2', suit='spades', value='1')
Card(rank='3', suit='spades', value='2')
Card(rank='4', suit='spades', value='3')
Card(rank='5', suit='spades', value='4')
Card(rank='6', suit='spades', value='5')
Card(rank='7', suit='spades', value='6')
Card(rank='8', suit='spades', value='7')
Card(rank='9', suit='spades', value='8')
Card(rank='10', suit='spades', value='9')
Card(rank='J', suit='spades', value='10')
Card(rank='K', suit='spades', value='11')
Card(rank='Q', suit='spades', value='12')
Card(rank='A', suit='spades', value='13')
Any idea how to do this?
source to share
You don't actually inline your list iteration as you think.
Change
def __init__(self):
self._cards = [Card(rank, suit, value)
for suit in self.suits
for rank in self.ranks
for value in self.card_value
]
to
def __init__(self):
self._cards = [Card(rank, suit, value)
for suit in self.suits
for rank, value in zip(self.ranks,\
self.card_value)
]
does what you want. Note that this is equivalent to:
def __init__(self):
self._cards = []
for suit in self.suits:
for rank, value in zip(self.ranks, self.card_value):
self._cards+=[Card(rank, suit, value)]
Also, as hepner said, or put in place by Jerimi,
value
is not an independent attribute of aCard
; this is a functionrank
.
This means that you can use value
for self.card_value
for each element self.suits
and then get the corresponding rank
one based value
on which you are working on.
more details
after your comment / questionYou define ranks
as
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
and then based on ranks
, you define card_value
like this
card_value = [str(n + 1) for n in range(len(ranks))]
Which clearly shows the relationship between the two objects: each list item card_value
has / has a direct conversion / correspondence / to each list item ranks
.
just for free I would put s
on the pointer name self.card_value
for clarity. those.self.card_values
source to share