将微缩列表添加到更大的列表中

时间:2016-08-18 20:45:08

标签: python python-3.x list append tuples

我正在创建一个python应用程序来玩游戏Perudo(或骗子的骰子)。

我正在尝试创建一个函数来计算允许玩家(或AI)进行的所有可能移动并返回它们的列表,以便它可以拒绝非法移动。

转动被存储为2个数字的列表,例如[10,6]代表十六。 如果起始变量currentbid[19,3](十九个三分球)并且有20个骰子在玩,那么唯一可能的动作是19个四分球,19个五分球,19个六分球,20个二分球,20个三分球,20个四分球,20五和二十六。不允许召唤一个。 该程序应输出以上内容:

[[19,4],[19,5],[19,6],[20,2],[20,3],[20,4],[20,5],[20,6]]

但输出为:

[[20,6],[20,6],[20,6],[20,6],[20,6],[20,6],[20,6],[20,6]]

我做错了什么?

def calcpossiblemoves(self, currentbid, totalnoofdice):
    self.possiblemoves = []  # Create a list of possible moves that will be added too

    self.bid = currentbid

    while self.bid[0] <= totalnoofdice:

        while self.bid[1] < 6:
            self.bid[1] += 1
            self.possiblemoves.append(self.bid)     # <- I think the problem is something to do with this line
            print(self.possiblemoves) #For tracking the process

        # Increase 1st number, reset 2nd number to 1

        self.bid[0] += 1
        self.bid[1] = 1 # Which will get increased to 2
        #print("Reached 6")
    return self.possiblemoves

4 个答案:

答案 0 :(得分:1)

你最好考虑一个基数为6的数字,你可以有效地获得20个骰子的数字范围,包括0到126个。

current_bid = [19, 3]
offset = current_bid[0] * 6 + current_bid[1]
# 117 - and divmod(117, 6) == (19, 3)

因此,要获得剩余的有效出价,您可以在117 - 126的范围内进行数学计算,并获得有效的骰子数和余数。

valid_bids_with1s = ([n // 6, n % 6 + 1] for n in range(offset, 126))
valid_bids = [[a, b] for a, b in valid_bids_with1s if b != 1]

这给了你:

[[19, 4],
 [19, 5],
 [19, 6],
 [20, 2],
 [20, 3],
 [20, 4],
 [20, 5],
 [20, 6]]

答案 1 :(得分:1)

问题在于您使用的是list s,它们是可变对象,而您正在创建引用,而不是副本。您可以通过每次复制self.bid列表来解决此问题,但最“pythonic”解决方案不是使用list,而是使用tuple,而是:

def calcpossiblemoves(self, currentbid, totalnoofdice):
    possiblemoves = []

    numberof, value = currentbid

    while numberOf <= totalnoofdice:

        while value < 6:
            value += 1
            possiblemoves.append((numberOf, value))

        # Increase 1st number, reset 2nd number to 1

        numberof += 1
        value = 1 # Which will get increased to 2
        #print("Reached 6")
    return self.possiblemoves

请注意,这不会更新self.bid(但您可以轻松添加),并且您会获得list个不可变的tuple

编辑:因为tuple是不可变的,所以我使用元组解包来创建两个变量。这是为了防止出现以下问题:

>>> bid = (1, 2)
>>> bid[0] += 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

我可以写bid = (bid[0]+1, bid[1]),但使用两个变量,imho,更容易理解。

一般来说,确保list的所有成员的意思相同,而tupledict中的值含义不同,这是一个很好的经验法则,或自定义容器,例如NamedTuple或自定义类。

在此示例中,外部list包含多个出价,但每个内部list都有个骰子值< / em>,表示list可能是错误的类型。

答案 2 :(得分:0)

您在列表中附加相同的对象,这说明您获得了最后一次值的6倍。

替换

self.possiblemoves.append(self.bid)     # <- I think the problem is something to do with this line

通过

self.possiblemoves.append(list(self.bid)) # make a copy of the list to make it independent from next modifications on self.bid

答案 3 :(得分:0)

问题是对self.bid的引用。它在列表中反复出现相同的变量,这意味着当您在循环中更新它时,您将更新每个实例(在这种情况下,列表中的所有变量)。我已经改写了你想要做的工作,以便你想要保持相同的格式,但正如其他人所说,你可以从编码的角度清理它。

def calcpossiblemoves(currentbid, totalnoofdice):
    possiblemoves = []# in range(totalnoofdice)  #Create a list of possible moves that will be added too

    bid = currentbid
    available_bid = None

    while bid[0] <= totalnoofdice:

        while bid[1] < 6:
            bid[1] += 1
            available_bid = [bid[0],bid[1]]
            possiblemoves.append(available_bid)     # <- I think the problem is something to do with this line
            print(possiblemoves) #For tracking the process

        # Increase 1st number, reset 2nd number to 1

        bid[0] += 1
        bid[1] = 1 # Which will get increased to 2
        #print("Reached 6")
    return possiblemoves

calcpossiblemoves([19,3],20)