列表第二次运行失败

时间:2017-06-19 17:02:33

标签: python list

我目前正在尝试编写一个数学卡片技巧,它会询问用户他们的随机卡片是什么堆。但是,它第二次运行(“技巧阶段”必须发生3次才能使用该技巧)列表索引超出范围。我不确定问题究竟在哪里,并将附加当前版本,以便您可以尝试运行它以查看更清晰。谢谢!

import random

def makedeck():
  listy = []
  cardsindeck = 0
  while cardsindeck != 21:
    suit = random.randint(1,4)
    if suit == 1:
      suit = "D"
    elif suit == 2:
      suit = "H"
    elif suit == 3:
      suit = "S"
    else:
      suit = "C"
    cardtype = random.randint(1,13)
    if cardtype == 1:
      card = "A"
    elif cardtype == 2:
      card = "2"
    elif cardtype == 3:
      card = "3"
    elif cardtype == 4:
      card = "4"
    elif cardtype == 5:
      card = "5"
    elif cardtype == 6:
      card = "6"
    elif cardtype == 7:
      card = "7"
    elif cardtype == 8:
      card = "8"
    elif cardtype == 9:
      card = "9"
    elif cardtype == 10:
      card = "10"
    elif cardtype == 11:
      card = "J"
    elif cardtype == 12:
      card = "Q"
    else:
      card = "K"
    cardandsuit = (card + suit)
    if cardandsuit not in listy:
      listy.append(cardandsuit)
      cardsindeck = cardsindeck + 1
  return listy

def dealdeck(listy):
  list1 = []
  list2 = []
  list3 = []
  for i in range(len(listy)):
    if i % 3 == 0:
      list1.append(listy[i])
    elif i % 3 == 1:
      list2.append(listy[i])
    else:
      list3.append(listy[i])
  return[list1, list2, list3]

def makepiles(pile1,pile2,pile3):
  print("Pile 1\t\tPile 2\t\t Pile 3\t\t")
  for i in range(7):
    print(pile1[i],"\t\t",pile2[i],"\t\t",pile3[i],"\t\t")

def usercardpile():
  userinput = input("What pile is your card in?")
  if userinput == "1" or userinput.title() == "One":
    return 1
  elif userinput == "2" or userinput.title() == "Two":
    return 2
  elif userinput == "3" or userinput.title() == "Three":
    return 3
  else:
    print("Please only write 1, 2 or 3")
    return usercardpile()


listy = makedeck()
pile1, pile2, pile3 = dealdeck(listy)
for i in range(1,4):
  newlisty = makepiles(pile1,pile2,pile3)
  userspile = usercardpile()
  if userspile == 1:
    newlisty = (pile2,pile1,pile3)
  elif userspile == 2:
    newlisty = (pile1,pile2,pile3)
  else:
    newlisty = (pile1,pile3,pile2)
  pile1, pile2, pile3 = dealdeck(newlisty)

print("Your card is",newlisty[10])

2 个答案:

答案 0 :(得分:1)

这一行代码存在一个问题:

newlisty = makepiles(pile1, pile2, pile3)

您希望makepiles返回3个列表,而返回None(未返回明确的项目)。

我想如果你要从那个功能中归还那些桩,那就可以了。

另一件事是,你这样做:

newlisty = (pileX, pileY, pileZ)

这将创建一个列表元组,您将迭代整个列表而不是单个卡。我相信你想要

newlisty = pile1 + pile3 + pile2`

这将通过线性组合较小的桩来创建21个元素的复合列表。

其他评论:

考虑在dict s中存储您的卡片类型和卡片类型。这样,您可以快速查找并生成堆,而无需编写一长串if语句。例如:

你可以减少

cardtype = random.randint(1,13)
if cardtype == 1:
  card = "A"
elif cardtype == 2:
  card = "2"
elif cardtype == 3:
  card = "3"
elif cardtype == 4:
  card = "4"
elif cardtype == 5:
  card = "5"
elif cardtype == 6:
  card = "6"
elif cardtype == 7:
  card = "7"
elif cardtype == 8:
  card = "8"
elif cardtype == 9:
  card = "9"
elif cardtype == 10:
  card = "10"
elif cardtype == 11:
  card = "J"
elif cardtype == 12:
  card = "Q"
else:
  card = "K"

要...

cardtype_lookup = { 1 : 'A', 2 : '2', 3 : '3', .... 12 : 'K' } 

card = cardtype_lookup[random.randint(1, 13)]

......等等。

答案 1 :(得分:0)

我认为除了最后的迭代之外,你的代码还会遇到一些问题。以下是一些建议以及我认为可以实现您目的的评论。

from random import shuffle

# Function for generating 21 random cards
def makedeck():

    # Create 52 cards by suit and cardtype
    listy = [card + suit for card in ['A','2','3','4','5','6','7','8','9','10','J','Q','K'] for suit in ['D','H','S','C']]

    # Shuffle the list
    shuffle(listy)

    # Choose only the first 21 items of that list
    listy = listy[:21]

    return listy

# Function for dividing 21-card deck into 3 equally-sized piles
def dealdeck(listy):

    # Iterate over listy, stepping by 3, starting with the first, second, and third item
    list1 = listy[::3]
    list2 = listy[1::3]
    list3 = listy[2::3]

    # Return the three lists as three items to correspond to the three piles of the call
    return list1, list2, list3

# This works
def makepiles(pile1,pile2,pile3):
    print("Pile 1\t\tPile 2\t\t Pile 3\t\t")
    for i in range(7):
        print(pile1[i],"\t\t",pile2[i],"\t\t",pile3[i],"\t\t")

# This works
def usercardpile():
    userinput = input("What pile is your card in?")
    if userinput == "1" or userinput.title() == "One":
        return 1
    elif userinput == "2" or userinput.title() == "Two":
        return 2
    elif userinput == "3" or userinput.title() == "Three":
        return 3
    else:
        print("Please only write 1, 2 or 3")
        return usercardpile()

listy = makedeck()
pile1, pile2, pile3 = dealdeck(listy)
for i in range(1,4):
    # Because this function does not return anything, it should be run on its own, and not assigned to a variable
    makepiles(pile1,pile2,pile3)

    userspile = usercardpile()

    # Now you want to re-order the piles based on user input. Because these are lists, you can simply add them together in a new order to create a newly arranged list
    if userspile == 1:
        newlisty = pile2 + pile1 + pile3
    elif userspile == 2:
        newlisty = pile1 + pile2 + pile3
    else:
        newlisty = pile1 + pile3 + pile2

    # Now you create new piles based on the re-sorted list and re-iterate
    pile1, pile2, pile3 = dealdeck(newlisty)

# Uses .format method instead
print("Your card is {}".format(newlisty[10]))