在Python类中使用__iter_方法实现递归函数



所以我正在处理一个问题,我要创建一个Python类来生成列表的所有置换,我遇到了以下问题:

  1. 我可以用一个简单的递归函数很容易地完成这项工作,但作为一个类,我似乎想使用iter方法。我的方法调用了一个递归函数(list_all),该函数与我的iter几乎相同,这非常令人不安。如何修改递归函数以符合iter的最佳实践
  2. 我写了这个代码,看到它起作用了,我觉得我不理解它!我试图在测试用例中逐行跟踪代码,但对我来说,每次列表中的第一个元素似乎都被冻结了,而列表的其余部分则被打乱了。相反,输出的顺序出乎意料。我不明白什么

谢谢!

class permutations():
  def __init__(self, ls):
    self.list = ls
  def __iter__(self):
    ls = self.list
    length = len(ls)
    if length <= 1:
      yield ls
    else:
      for p in self.list_all(ls[1:]):
        for x in range(length):
          yield p[:x] + ls[0:1] + p[x:]  
  def list_all(self, ls):
    length = len(ls)
    if length <= 1:
      yield ls
    else:
      for p in self.list_all(ls[1:]):
        for x in range(length):
          yield p[:x] + ls[0:1] + p[x:]

只需从__iter__:调用self.list_all

class permutations():
  def __init__(self, ls):
    self.list = ls
  def __iter__(self):
    for item in self.list_all(self.list):
      yield item
  def list_all(self, ls):
    length = len(ls)
    if length <= 1:
      yield ls
    else:
      for p in self.list_all(ls[1:]):
        for x in range(length):
          yield p[:x] + ls[0:1] + p[x:]

您的list_all方法已经是一个生成器,因此您可以直接在__iter__:中返回它

class permutations():
    def __init__(self, ls):
        self.list = ls
    def __iter__(self):
        return self.list_all(self.list)
    def list_all(self, ls):
        length = len(ls)
        if length <= 1:
            yield ls
        else:
            for p in self.list_all(ls[1:]):
                for x in range(length):
                    yield p[:x] + ls[0:1] + p[x:]

这既能更清晰地读取,又能更快地执行。

您还可以选择在__iter__中定义list_all

class permutations2():
    def __init__(self, ls):
        self.list = ls
    def __iter__(self):
        def list_all(ls):
            length = len(ls)
            if length <= 1:
                yield ls
            else:
                for p in list_all(ls[1:]):
                    for x in range(length):
                        yield p[:x] + ls[0:1] + p[x:]
                    
        return list_all(self.list)

定时permutations与我的permutations2给出了几乎相同的结果。

最新更新