Clojure 和 Python 中的惰性无限序列

2024-02-29

以下是我能在 Clojure 和 Python 中找到的斐波那契数列的惰性无限序列的最佳实现:

Clojure:

(def fib-seq (lazy-cat [0 1]
 (map + fib-seq (rest fib-seq))))

示例用法:

 (take 5 fib-seq)

Python:

def fib():
 a = b = 1
 while True:
  yield a
  a,b = b,a+b

示例用法:

for i in fib():
  if i > 100:
    break
  else:
    print i

显然Python代码更加直观。

我的问题是:Clojure 中是否有更好(更直观和简单)的实现?

Edit

我正在打开一个后续问题Clojure 素数 https://stackoverflow.com/questions/1590716/clojure-prime-numbers-lazy-sequence


我同意帕维尔的观点,直觉就是主观的。因为我(慢慢地)开始了解 Haskell,所以我可以说出 Clojure 代码的作用,即使我一生中从未编写过一行 Clojure。所以我认为 Clojure 系列相当直观,因为我以前见过它并且我正在适应更实用的思维方式。

让我们考虑一下数学定义,好吗?

       { 0                   if x = 0 }
F(x) = { 1                   if x = 1 }
       { F(x - 1) + F(x - 2) if x > 1 }

从格式上看,这并不理想——这三个括号排列起来应该是一个巨大的括号——但谁在数呢?对于大多数具有数学背景的人来说,这是斐波那契数列的一个非常清晰的定义。让我们看看 Haskell 中的同样的事情,因为我比 Clojure 更了解它:

fib 0 = 0
fib 1 = 1
fib n = fibs (n - 1) + fibs (n - 2)

这是一个函数,fib,返回第 n 个斐波那契数。不完全是我们在 Python 或 Clojure 中所拥有的,所以让我们解决这个问题:

fibs = map fib [0..]

这使得fibs斐波那契数列的无限列表。fibs !! 1 is 1, fibs !! 2 is 1, fibs !! 10是 55,依此类推。然而,即使在像 Haskell 这样依赖于高度优化的递归的语言中,这也可能是相当低效的。让我们看看 Haskell 中的 Clojure 定义:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

前几个字符非常简单:0 : 1 :创建一个包含元素 0 和 1 以及更多元素的列表。但剩下的是什么?出色地,fibs是我们已经得到的列表,并且tail fibs称为tail到目前为止我们列表中的函数,它返回从第二个元素开始的列表(有点像Python中的说法fibs[1:])。所以我们拿这两个列表 -fibs and tail fibs- 我们将它们用拉链拉在一起+函数(运算符) - 也就是说,我们将每个的匹配元素相加。我们看看吧:

fibs       = 0 : 1 : ...
tail fibs  = 1 : ...
zip result = 1 : ...

所以我们的下一个元素是 1!但随后我们将其添加回我们的fibs列出来,看看我们得到了什么:

fibs       = 0 : 1 : 1 : ...
tail fibs  = 1 : 1 : ...
zip result = 1 : 2 : ...

我们这里有一个递归列表定义。当我们在末尾添加更多元素时fibs跟我们zipWith (+) fibs (tail fibs)位,添加元素时我们可以使用更多元素。请注意,Haskell 默认情况下是惰性的,因此仅创建一个像这样的无限列表不会导致任何崩溃(只是不要尝试打印它)。

因此,虽然这在理论上可能与我们之前的数学定义相同,但它将结果保存在我们的fibs列表(某种自动记忆),我们很少遇到在简单的解决方案中可能遇到的问题。为了完整起见,让我们定义我们的fib就我们的新功能而言fibs list:

fib n = fibs !! n

如果我还没有失去你,那很好,因为这意味着你了解 Clojure 代码。看:

(def fib-seq (lazy-cat [0 1]
 (map + fib-seq (rest fib-seq))))

我们列出一个清单,fib-seq。它从两个元素开始,[0 1],就像我们的 Haskell 示例一样。我们对这两个初始元素进行惰性连接(map + fib-seq (rest fib-seq))- 假设rest做同样的事情tail在 Haskell 中,我们只是将列表与自身以较低的偏移量组合起来,然后将这两个列表与+运算符/函数。

在头脑中思考了几次并探索了一些其他示例之后,这种生成斐波那契数列的方法至少变得半直观了。它至少足够直观,让我能够以我不懂的语言发现它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Clojure 和 Python 中的惰性无限序列 的相关文章

  • 使用单个文件的 Python 日志记录(函数名、文件名、行号)

    我正在尝试了解应用程序的工作原理 为此 我将调试命令插入作为每个函数主体的第一行 目的是记录函数的名称以及向日志输出发送消息的行号 代码内 最后 由于这个应用程序由许多文件组成 我想创建一个日志文件 以便我可以更好地理解应用程序的控制流 这
  • 为什么 pandas 在简单的数学运算上比 numpy 更快?

    最近 我观察到 pandas 的乘法速度更快 我在下面的例子中向您展示了这一点 如此简单的操作怎么可能做到这一点 这怎么可能呢 pandas 数据帧中的底层数据容器是 numpy 数组 测量 我使用形状为 10k 10k 的数组 数据框 i
  • 如何在 QTableView 标题中单击鼠标右键单击上下文菜单?

    下面的示例代码 很大程度上受到here http www saltycrane com blog 2007 12 pyqt 43 qtableview qabstracttablemodel 有一个右键单击上下文菜单 当用户单击表中的单元格
  • sy.sympify(str(表达式)) 不等于表达式

    据我了解 str将 SymPy 表达式转换为字符串并sympify将字符串转换为 SymPy 表达式 因此 我希望以下内容成立 对于合理的表达 gt gt gt sy sympify str expr expr True 我尝试过这个 确实
  • Django 查询:“datetime + delta”作为表达式

    好吧 我的问题如下 假设我有下一个模型 这是一个简单的情况 class Period models Model name CharField field specs here start date DateTimeField field s
  • Python函数组成

    我尝试使用良好的语法来实现函数组合 这就是我所得到的 from functools import partial class compfunc partial def lshift self y f lambda args kwargs s
  • 如何在动态执行的代码字符串中使用inspect.getsource?

    如果我在文件中有这段代码 import inspect def sample p1 print p1 return 1 print inspect getsource sample 当我运行脚本时 它按预期工作 在最后一行 源代码sampl
  • 将多索引转换为行式多维 NumPy 数组。

    假设我有一个类似于以下示例的 MultiIndex DataFrame多索引文档 http pandas pydata org pandas docs stable advanced html gt gt gt df 0 1 2 3 fir
  • 烧瓶 - 404 未找到

    我是烧瓶开发的新手 这是我在烧瓶中的第一个程序 但它向我显示了这个错误 在服务器上找不到请求的 URL 如果您输入了网址 请手动检查拼写并重试 这是我的代码 from flask import Flask app Flask name ap
  • 样本()和r样本()有什么区别?

    当我从 PyTorch 中的发行版中采样时 两者sample and rsample似乎给出了类似的结果 import torch seaborn as sns x torch distributions Normal torch tens
  • Django Web 应用程序中的 SMTP 问题

    我被要求向使用 Django Python 框架实现的现有程序添加一个功能 此功能将允许用户单击一个按钮 该按钮将显示一个小对话框 表单以输入值 我确实编写了一些代码 显示电子邮件已发送的消息 但实际上 它没有发送 My code from
  • 如何将 Pyspark Dataframe 标题设置到另一行?

    我有一个如下所示的数据框 col1 col2 col3 id name val 1 a01 X 2 a02 Y 我需要从中创建一个新的数据框 使用 row 1 作为新的列标题并忽略或删除 col1 col2 等行 新表应如下所示 id na
  • 一个类似 dict 的 Python 类

    我想编写一个自定义类 其行为类似于dict 所以 我继承自dict 不过 我的问题是 我是否需要创建一个私有的dict我的成员 init 方法 我不明白这个有什么意义 因为我已经有了dict如果我只是继承自的行为dict 谁能指出为什么大多
  • 使用 Windows 任务计划程序安排 [Virtualenv 相关] Python 脚本

    I want to schedule a python script to start at 3AM and break at 5PM every weekday However the problem arises when I need
  • 导入目录下的所有模块

    有没有办法导入当前目录中的所有模块 并返回它们的列表 例如 对于包含以下内容的目录 mod py mod2 py mod3 py 它会给你
  • 错误:尝试使用 scrappy 登录时出现 raise ValueError("No element found in %s" % response)

    问题描述 我想从我大学的bbs上抓取一些信息 这是地址 http bbs byr cn http bbs byr cn下面是我的蜘蛛的代码 from lxml import etree import scrapy try from scra
  • 无法将matplotlib安装到pycharm

    我最近开始使用Python速成课程学习Python编程 我陷入困境 因为我无法让 matplotlib 在 pycharm 中工作 我已经安装了pip 我已经通过命令提示符使用 pip 安装了 matplotlib 现在 当我打开 pych
  • 如何在supervisord中设置组?

    因此 我正在设置 Supervisord 并尝试控制多个进程 并且一切正常 现在我想设置一个组 以便我可以启动 停止不同的进程集 而不是全部或全无 这是我的配置文件的片段 group tapjoy programs tapjoy game1
  • python 日志记录替代方案 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 蟒蛇记录模块 http docs python org library logging html使用起来
  • 用 Beautiful Soup 进行抓取:为什么 get_text 方法不返回该元素的文本?

    最近我一直在用 python 开发一个项目 其中涉及抓取一些网站的一些代理 我遇到的问题是 当我尝试抓取某个知名代理站点时 当我要求 Beautiful Soup 查找 IP 在代理表中的位置时 它并没有按照我的预期执行操作 我将尝试查找每

随机推荐