关于python:cant solve”inc()接受1个位置参数,但给出2个”

Cant Solve “inc() takes 1 positional argument but 2 were given”

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

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

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

和poslist_all(2,2)

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

所以我想把这个列表变成一个迭代器,然后想到了这个代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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)

但这总会回来的

1
2
3
4
5
6
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

是什么导致了这个错误?如何解决?有更多的Python式的方法吗?


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

1
2
3
4
5
def inc(self, pnum):
    if ...:
        return ...
    else:
        return ...


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

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

1
2
3
4
5
6
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的内置函数。


变化:

1
2
3
4
5
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)

到:

1
2
3
4
5
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)