python - 从 Swift 中的无限迭代器或生成器中获取前 N 个元素

标签 python swift iterator generator

我在 Python 中经常使用生成器。现在我尝试在 Swift 中做类似的事情。

来自 Python 中的无限阶乘生成器。

def gen_factorial():
  current = 1
  N = 1
  while True:
    yield current
    N += 1
    current *= N

Swift 版本是

struct gen_factorial: Sequence, IteratorProtocol 
{
  var current = 1
  var N = 1
  mutating func next()-> Int?{
    defer {
      N += 1
      current *= N
    }
    return current
  }
}

我通过使用前 4 个元素来测试它

zip(1...4, 
    gen_factorial()
   ).map{$1}

并按预期获得 1, 2, 6, 24

但是当我想编写一个辅助函数 take(n, gen) 来简化它时,我却做不到。

func take(_ n: Int, _ it: AnyIterator<Int>) -> [Int]{
  return zip(1...n, it).map {$1}
}

take(4, gen_factorial())

错误信息是

error: cannot convert value of type 'gen_factorial' to expected argument type 'AnyIterator<Int>'

如果不是 AnyIterator,它应该是什么类型?

我对 Swift 还很陌生。请帮忙。

最佳答案

AnyIterator 是符合 Iterator(和 Sequence)协议(protocol)的具体类型。为了将迭代器传递给该函数,您必须将其包装到 AnyIterator 中:

print(take(4, AnyIterator(gen_factorial())))
// [1, 2, 6, 24]

更好的解决方案是使函数通用,以便它采用任意序列类型作为参数:

func take<S: Sequence>(_ n: Int, _ it: S) -> [S.Element]{
    return zip(1...n, it).map {$1}
}

print(take(4, gen_factorial()))
// [1, 2, 6, 24]

备注:

  • 您可以使用现有的 prefix(_ maxLength:) 来代替辅助函数。 序列的方法:

    print(Array(gen_factorial().prefix(4)))
    // [1, 2, 6, 24]
    
  • 大驼峰式大小写类型的 Swift 命名约定。

关于python - 从 Swift 中的无限迭代器或生成器中获取前 N 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56914614/

相关文章:

python - 同时按日期和ID分组 Pandas 数据框

python - BucketIterator 抛出 'Field' 对象没有属性 'vocab'

python - query.next() 慢吗?

python - 从 Bash 或 Python 检查邮件主题

python - Python/ES6 生成器也是协程吗?

ios - 带有 UITableViewController 的 searchResultsController 隐藏了导航栏,如何防止呢?

swift - 在 Swift 中,我可以编写一个通用函数来调整数组的大小吗?

c++ - 在正向和反向迭代之间切换

python - 尝试加载时引发导入错误 'blog.templatetags.blog_tags' : No module named 'markdown

swift - Xcode 6 不能用//取消注释字符串