2017-11-26 120 views
8

Python 3.6.3 Bir liste birbiri ardına olsa da döngü oluşturmanın bir yolu var mı?Tek bir döngüde sıralı olarak birden çok liste arasında nasıl geçiş yapılır?

Örneğin

:

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

(Bu durumda, şu sigara yüz kartlarına sonra yüz kartlarına içinde döngü istiyorum.) Açık bilgi için

: Yukarıdaki satır bir atar:

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

Bu benim sorunum.

+0

Örneğiniz belirsiz. Beklenen sonuç/çıktı nedir? – timgeb

+0

@timgeb Örnekte, standart 52 kart destesi yapmaya çalışıyorum. Sorun şu ki, bir numaralı döngüye ihtiyaç duymadan numaralı kartlardan hemen sonra {"J", "Q", "K", "A"} ile yinelemek istiyorum. – Josh

+0

@schwobaseggl Bu satır bir tür hata atar: "TypeError: desteklenmeyen işlenen türü (ler) için +: 'aralık' ve 'liste'" – Josh

cevap

17

range, Python3'te list döndürmez, bu nedenle range(2, 10) + ["J", "Q", "K", "A"] çalışır, ancak list(range(2, 10)) + ["J", "Q", "K", "A"] yapar. Ayrıca Iterables bitiştirmek için itertools.chain kullanabilirsiniz:

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" 
] 

iç içe anlama, tabii ki, aynı zamanda bir util kullanabileceğiniz bir kartezyen ürünü teşkil etmez:

Python3 yılında
from itertools import product 
deck = list(product(chain(range(2, 10), "JQKA"), "HCDS")) 
8

mevcut kodu ile sorun buradadır:

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

Öncelikle, aksi 10 sayısı ile kartları atlanmıştır, range(2, 11) olmalıdır. İkincisi, menzil ve listesine katılmak için, bunu böyle yapmanız gerekecek:

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

Yani nihai sonuç olacaktır:

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

Bu size arzu verecektir düşünüyorum çıktı (önce tüm yüz olmayan kartlar, daha sonra tüm yüz kartları).

+1

Bu işe yarayacaktır, ancak @schwobaseggl itertools kullanarak daha iyi bir çözüme sahiptir, çünkü bir listenin gereksiz bir şekilde yapılandırılmasını gerektirmez ve sonra birleştirme işlemini listeler. –

3

kullanabileceğiniz ancak ne istediğinizi için

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

'List'' için arama yapmanıza gerek yok:' [* aralık (2, 10), "J", "Q", "K", "A"] 'yeterlidir. (Ya da [* aralığı (2, 11), * "JQKA"] '.) –

+0

@MarkDickinson bilmek güzel. Lütfen son düzenlememe bakın. – Ajax1234

5

Bkz @ schwobaseggl en çözümünü, ama genellikle 2 karakter dizesi olarak kartlarını temsil etmesini tercih: açma

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

Bu benim görüşüme göre daha okunaklı ve hala bir sıralama sırası gibi davranacak. Alacağınız yapmak yanlışlıkla sadece Odaklama

+0

'*' için gerek yok – schwobaseggl

2

:

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

Sana bir açıklama verecektir.

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

yazdırır:

Geçerli kod yılında Python 2 çalışır

[(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')] 

Python 3size kullanmak zorunda 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) 

pr olacak 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')] 

Bir değişmez dizi tipini değil, bir liste oluşturmak yok Python 3'te list() çünkü range() kullanmak zorunda.

İlgili konular