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 中的惰性无限序列 的相关文章

  • 如何在刻度标签和轴之间添加空间

    我已成功增加刻度标签的字体 但现在它们距离轴太近了 我想在刻度标签和轴之间添加一点呼吸空间 如果您不想全局更改间距 通过编辑 rcParams 并且想要更简洁的方法 请尝试以下操作 ax tick params axis both whic
  • 将字符串转换为带有毫秒和时区的日期时间 - Python

    我有以下 python 片段 from datetime import datetime timestamp 05 Jan 2015 17 47 59 000 0800 datetime object datetime strptime t
  • 如何使用固定的 pandas 数据框进行动态 matplotlib 绘图?

    我有一个名为的数据框benchmark returns and strategy returns 两者具有相同的时间跨度 我想找到一种方法以漂亮的动画风格绘制数据点 以便它显示逐渐加载的所有点 我知道有一个matplotlib animat
  • 如何生成给定范围内的回文数列表?

    假设范围是 1 X 120 这是我尝试过的 gt gt gt def isPalindrome s check if a number is a Palindrome s str s return s s 1 gt gt gt def ge
  • DreamPie 不适用于 Python 3.2

    我最喜欢的 Python shell 是DreamPie http dreampie sourceforge net 我想将它与 Python 3 2 一起使用 我使用了 添加解释器 DreamPie 应用程序并添加了 Python 3 2
  • 如何等到 Excel 计算公式后再继续 win32com

    我有一个 win32com Python 脚本 它将多个 Excel 文件合并到电子表格中并将其另存为 PDF 现在的工作原理是输出几乎都是 NAME 因为文件是在计算 Excel 文件内容之前输出的 这可能需要一分钟 如何强制工作簿计算值
  • 如何使用 Scrapy 从网站获取所有纯文本?

    我希望在 HTML 呈现后 可以从网站上看到所有文本 我正在使用 Scrapy 框架使用 Python 工作 和xpath body text 我能够获取它 但是带有 HTML 标签 而且我只想要文本 有什么解决办法吗 最简单的选择是ext
  • 打破嵌套循环[重复]

    这个问题在这里已经有答案了 有没有比抛出异常更简单的方法来打破嵌套循环 在Perl https en wikipedia org wiki Perl 您可以为每个循环指定标签 并且至少继续一个外循环 for x in range 10 fo
  • 为 pandas 数据透视表中的每个值列定义 aggfunc

    试图生成具有多个 值 列的数据透视表 我知道我可以使用 aggfunc 按照我想要的方式聚合值 但是如果我不想对两列求和或求平均值 而是想要一列的总和 同时求另一列的平均值 该怎么办 那么使用 pandas 可以做到这一点吗 df pd D
  • 安装后 Anaconda 提示损坏

    我刚刚安装张量流GPU创建单独的后环境按照以下指示here https github com antoniosehk keras tensorflow windows installation 但是 安装后当我关闭提示窗口并打开新航站楼弹出
  • 运行多个 scrapy 蜘蛛的正确方法

    我只是尝试使用在同一进程中运行多个蜘蛛新的 scrapy 文档 http doc scrapy org en 1 0 topics practices html但我得到 AttributeError CrawlerProcess objec
  • python pandas 中的双端队列

    我正在使用Python的deque 实现一个简单的循环缓冲区 from collections import deque import numpy as np test sequence np array range 100 2 resha
  • 在pyyaml中表示具有相同基类的不同类的实例

    我有一些单元测试集 希望将每个测试运行的结果存储为 YAML 文件以供进一步分析 YAML 格式的转储数据在几个方面满足我的需求 但测试属于不同的套装 结果有不同的父类 这是我所拥有的示例 gt gt gt rz shorthand for
  • 使用 OpenPyXL 迭代工作表和单元格,并使用包含的字符串更新单元格[重复]

    这个问题在这里已经有答案了 我想使用 OpenPyXL 来搜索工作簿 但我遇到了一些问题 希望有人可以帮助解决 以下是一些障碍 待办事项 我的工作表和单元格数量未知 我想搜索工作簿并将工作表名称放入数组中 我想循环遍历每个数组项并搜索包含特
  • 循环中断打破tqdm

    下面的简单代码使用tqdm https github com tqdm tqdm在循环迭代时显示进度条 import tqdm for f in tqdm tqdm range 100000000 if f gt 100000000 4 b
  • 通过数据框与函数进行交互

    如果我有这样的日期框架 氮 EG 00 04 NEG 04 08 NEG 08 12 NEG 12 16 NEG 16 20 NEG 20 24 datum von 2017 10 12 21 69 15 36 0 87 1 42 0 76
  • Nuitka 未使用 nuitka --recurse-all hello.py [错误] 编译 exe

    我正在尝试通过 nuitka 创建一个简单的 exe 这样我就可以在我的笔记本电脑上运行它 而无需安装 Python 我在 Windows 10 上并使用 Anaconda Python 3 我输入 nuitka recurse all h
  • 设置 torch.gather(...) 调用的结果

    我有一个形状为 n x m 的 2D pytorch 张量 我想使用索引列表来索引第二个维度 可以使用 torch gather 完成 然后然后还设置新值到索引的结果 Example data torch tensor 0 1 2 3 4
  • VSCode:调试配置中的 Python 路径无效

    对 Python 和 VSCode 以及 stackoverflow 非常陌生 直到最近 我已经使用了大约 3 个月 一切都很好 当尝试在调试器中运行任何基本的 Python 程序时 弹出窗口The Python path in your
  • 在 Pandas DataFrame Python 中添加新列[重复]

    这个问题在这里已经有答案了 例如 我在 Pandas 中有数据框 Col1 Col2 A 1 B 2 C 3 现在 如果我想再添加一个名为 Col3 的列 并且该值基于 Col2 式中 如果Col2 gt 1 则Col3为0 否则为1 所以

随机推荐