'Improving a List Comprehension
The list comprehension below achieves the desired result/output:
- Each tuple in the list is indexed sequentially
- The names are grouped together by suit
- The names are in a consistent order
Code (deck of cards toy example):
Suits = ["Hearts"]*3 +["Diamonds"]*3
Names = ["Two","Ten","King"]
z = [(i,Names[(i-1)%3],Suits[((i-1)%6)]) for i in range(1,7)]
Output z:
[(1, 'Two', 'Hearts'),
(2, 'Ten', 'Hearts'),
(3, 'King', 'Hearts'),
(4, 'Two', 'Diamonds'),
(5, 'Ten', 'Diamonds'),
(6, 'King', 'Diamonds')]
It works because the original Suits list was changed from ["Hearts","Diamonds"] to["Hearts"]*3 +["Diamonds"]*3.
This feels contrived; although it works, I'm looking for a better solution.
Solution 1:[1]
Using enumerate and itertools.product:
from itertools import product
ranks = ["Two", "Ten", "King"]
suits = ["Hearts", "Diamonds"]
z = [(i, r, s) for i, (s, r) in enumerate(product(suits, ranks), start=1)]
Output:
[(1, 'Two', 'Hearts'),
(2, 'Ten', 'Hearts'),
(3, 'King', 'Hearts'),
(4, 'Two', 'Diamonds'),
(5, 'Ten', 'Diamonds'),
(6, 'King', 'Diamonds')]
Solution 2:[2]
You can use itertools.product and enumerate:
from itertools import product
suits = ["Hearts", "Diamonds"]
sames = ["Two","Ten","King"]
cards = [(index, suit, rank) for index, (suit, rank) in enumerate(product(sames, suits), start=1)]
print(cards)
Solution 3:[3]
you could use a two level nested comprehension with enumerate to get numbering:
Suits = ["Hearts","Diamonds"]
Names = ["Two","Ten","King"]
r = [(j+i,n,s) for j,s in enumerate(Suits)
for i,n in enumerate(Names,j*len(Suits)+1) ]
print(*r,sep="\n")
(1, 'Two', 'Hearts')
(2, 'Ten', 'Hearts')
(3, 'King', 'Hearts')
(4, 'Two', 'Diamonds')
(5, 'Ten', 'Diamonds')
(6, 'King', 'Diamonds')
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | kaya3 |
| Solution 2 | BrokenBenchmark |
| Solution 3 | Alain T. |
