2017-11-26 7 views
8

In Python 3.6.3 Gibt es eine Möglichkeit, eine Liste nach der anderen zu durchlaufen?Wie durchläuft man mehrere Listen nacheinander mit einer Schleife?

Zum Beispiel:

deck = [(value, suit) for value in range(2, 11) + 
      ["J", "Q", "K", "A"] for suit in ["H", "C", "D", "S"]] 

(In diesem Fall möchte ich, nachdem die Nicht-Gesicht Karten richtig das Gesicht Karten durchgeschleift.)

Zur Klarstellung: Die obige Linie wirft ein:

TypeError: unsupported operand type(s) for +: 'range' and 'list' 

Das ist mein Problem.

+0

Ihr Beispiel ist unklar. Was ist das erwartete Ergebnis? – timgeb

+0

@timgeb Im Beispiel versuche ich, ein Standarddeck von 52 Karten zu machen. Das Problem ist, dass ich gleich nach den nummerierten Karten durch {J, Q, K, A} iterieren möchte, ohne eine zweite Schleife zu benötigen. – Josh

+0

@schwobaseggl Diese Zeile löst einen Typfehler aus: "TypeError: nicht unterstützte Operandentypen für +: 'range' und 'list'" – Josh

Antwort

17

range nicht ein list in Python3, kehren so nicht range(2, 10) + ["J", "Q", "K", "A"] nicht funktionieren, aber list(range(2, 10)) + ["J", "Q", "K", "A"] tut. Sie können auch itertools.chain verwenden, um Iterables zu verketten:

from itertools import chain 

chain(range(2, 10), ["J", "Q", "K", "A"]) 
# or even shorter: 
chain(range(2, 10), "JQKA") # as strings themselves are iterables 

# so this comprehension will work 
deck = [ 
    (value, suit) 
    for value in chain(range(2, 10), "JQKA") 
    for suit in "HCDS" 
] 

Die verschachtelte Verständnis ist, natürlich, bilden ein kartesisches Produkt, das Sie auch util für verwenden können:

from itertools import product 
deck = list(product(chain(range(2, 10), "JQKA"), "HCDS")) 
8

Das Problem mit dem aktuellen Code ist hier:

range(2, 10) + ["J", "Q", "K", "A"] 

Zunächst einmal sollten sie range(2, 11), anders sein, Karten mit der Nummer 10 ausgelassen. Zweitens, um die Reichweite und die Liste zu kommen, werden Sie wie zu tun haben:

list(range(2, 11)) + ["J", "Q", "K", "A"] 

Also das Endergebnis sein wird:

deck = [(value, suit) for value in list(range(2, 11)) + ["J", "Q", "K", "A"] for suit in ["H", "C", "D", "S"]] 

ich denke, das Sie geben die gewünschte Ausgabe (zuerst alle Nicht-Bildkarten, dann alle Bildkarten).

+1

Das wird funktionieren, aber @schwobaseggl hat eine bessere Lösung mit itertools, da es keine unnötige Erstellung einer Liste erfordert und dann die Verkettung auflistet. –

3

In Python3, können Sie Auspacken:

deck = [(value, suit) for value in [*range(2, 10), "J", "Q", "K", "A"] for suit in ["H", "C", "D", "S"]] 
+1

Keine Notwendigkeit für die 'Liste' Aufruf dort:' [* Bereich (2, 10), "J", "Q", "K", "A"] 'ist genug. (Oder sogar '[* Reichweite (2, 11), *" JQKA "]'.) –

+0

@MarkDickinson gut zu wissen. Bitte sehen Sie meine letzte Änderung. – Ajax1234

5

See-Lösung @ schwobaseggl für das, was Sie wollen, aber ich ziehe es in der Regel Karten als 2 Zeichenfolge darzustellen, aber:

deck = [r+s for r in '23456789TJQKA' for s in 'hcds'] 

Dies ist meiner Meinung nach besser lesbar, und wird sich immer noch sehr wie ein Tupel von Rang, Anzug verhalten.

+0

Keine Notwendigkeit für das '*' – schwobaseggl

2

nur im Fehler Fokussierung erhalten Sie tun:

TypeError: unsupported operand type(s) for +: 'range' and 'list

Ich werde Ihnen eine Erklärung geben.

Ihre aktuellen Code nicht in Python arbeiten 2:

deck = [(value, suit) for value in range(2, 11) + ["J", "Q", "K", "A"] for suit in ["H", "C", "D", "S"]] 
print deck 

gedruckt wird:

[(2, 'H'), (2, 'C'), (2, 'D'), (2, 'S'), (3, 'H'), (3, 'C'), (3, 'D'), (3, 'S'), (4, 'H'), (4, 'C'), (4, 'D'), (4, 'S'), (5, 'H'), (5, 'C'), (5, 'D'), (5, 'S'), (6, 'H'), (6, 'C'), (6, 'D'), (6, 'S'), (7, 'H'), (7, 'C'), (7, 'D'), (7, 'S'), (8, 'H'), (8, 'C'), (8, 'D'), (8, 'S'), (9, 'H'), (9, 'C'), (9, 'D'), (9, 'S'), (10, 'H'), (10, 'C'), (10, 'D'), (10, 'S'), ('J', 'H'), ('J', 'C'), ('J', 'D'), ('J', 'S'), ('Q', 'H'), ('Q', 'C'), ('Q', 'D'), ('Q', 'S'), ('K', 'H'), ('K', 'C'), ('K', 'D'), ('K', 'S'), ('A', 'H'), ('A', 'C'), ('A', 'D'), ('A', 'S')] 

In Python 3 Sie verwenden haben list(range(2, 11)):

deck = [(value, suit) for value in list(range(2, 11)) + ["J", "Q", "K", "A"] for suit in ["H", "C", "D", "S"]] 
print(deck) 

wird pr int:

[(2, 'H'), (2, 'C'), (2, 'D'), (2, 'S'), (3, 'H'), (3, 'C'), (3, 'D'), (3, 'S'), (4, 'H'), (4, 'C'), (4, 'D'), (4, 'S'), (5, 'H'), (5, 'C'), (5, 'D'), (5, 'S'), (6, 'H'), (6, 'C'), (6, 'D'), (6, 'S'), (7, 'H'), (7, 'C'), (7, 'D'), (7, 'S'), (8, 'H'), (8, 'C'), (8, 'D'), (8, 'S'), (9, 'H'), (9, 'C'), (9, 'D'), (9, 'S'), (10, 'H'), (10, 'C'), (10, 'D'), (10, 'S'), ('J', 'H'), ('J', 'C'), ('J', 'D'), ('J', 'S'), ('Q', 'H'), ('Q', 'C'), ('Q', 'D'), ('Q', 'S'), ('K', 'H'), ('K', 'C'), ('K', 'D'), ('K', 'S'), ('A', 'H'), ('A', 'C'), ('A', 'D'), ('A', 'S')] 

Sie haben list() weil range() in Python 3 verwenden Typ eine unveränderliche Sequenz, nicht eine Liste nicht erstellen.

Verwandte Themen