2

我正在尝试开发两个自然数(不包括0)的元组列表的列表(让我们称为“l”),例如“a”可以是“l”的成员,如果len(a)== len并且对于每个“a”的成员(让我们调用 p),p[0] <= max 和 p[1] <= max

例如 poslist_all(max=2,len=1)

[[(1,1)],[(1,2)],[(2,1)],[(2,2)]]

和 poslist_all(2,2)

[[(1,1),(1,1)],[(1,1),(1,2)],[(1,1),(2,1)],[(1,1),(2,2)],...,[(2,2),(1,1)],[(2,2),(1,2)],[(2,2),(2,1)],[(2,2),(2,2)]]

所以我试图让这个列表成为一个迭代器并想出了这段代码,

class poslist_all:
    def __init__(self,max,len):
        self.max = max
        self.len = len
        self.iposlist = len*[(1,1)]
    def __iter__(self):
        return self
    def __next__(self):
        ml = self.maxlist()
        if ml:
            if ml[0] == 0:
                raise StopIteration
            else:
                toinc = ml[0]-1
                self.inc(ml[0] - 1)
                for i in range(ml[0],self.len-1):
                    self.iposlist[i] = (1,1)
                return self.iposlist
        else:
            self.inc(self.len - 1)
            return self.iposlist
    def maxlist(self):
        return [x for x,y in enumerate(self.iposlist) if y == (self.max,self.max)]
    def inc(pnum):
        if self.iposlist[pnum][1] == self.max:
            return (self.iposlist[pnum][0]+1,1)
        else:
            return (self.iposlist[pnum][0],self.iposlist[pnum][1]+1)

if __name__ == "__main__":
    for ps in poslist_all(2,2):
        print(ps)

但这总是返回

Traceback (most recent call last):
  File "./helper.py", line 33, in <module>
    for ps in poslist_all(2,2):
  File "./helper.py", line 22, in __next__
    self.inc(self.len - 1)
TypeError: inc() takes 1 positional argument but 2 were given

是什么导致了这个错误?如何解决?有没有更多的pythonic方式来做到这一点?

4

3 回答 3

11

类实例总是作为第一个参数传递给类的方法。尝试:

def inc(self, pnum):
    if ...:
        return ...
    else:
        return ...
于 2013-09-20T18:45:32.883 回答
4

其他人已经向您展示了如何摆脱错误,但我想解决实际问题。

确实有一种更好、更 Python 的方式来做你想做的事。itertools模块,特别是itertools.product()可以使这项任务变得更加简单。

import itertools as it

def create_possibilities(highest, per_list):
    tuples = it.product(range(1, highest+1), repeat=highest)
    all_possibilities = it.product(tuples, repeat=per_list)
    return all_possibilities

这将在迭代器上返回一个迭代器(我认为这至少接近正确的术语)。
如果您想要实际列表,请根据需要使用list()函数。

另外,请注意maxlen是糟糕的变量名;它们会影响 python 的内置函数。

于 2013-09-20T19:01:34.793 回答
3

改变:

def inc(pnum):
        if self.iposlist[pnum][1] == self.max:
            return (self.iposlist[pnum][0]+1,1)
        else:
            return (self.iposlist[pnum][0],self.iposlist[pnum][1]+1)

至:

def inc(self, pnum): # methods (in a class) require self
        if self.iposlist[pnum][1] == self.max:
            return (self.iposlist[pnum][0]+1,1)
        else:
            return (self.iposlist[pnum][0],self.iposlist[pnum][1]+1)
于 2013-09-20T18:46:31.373 回答