Clojure 中的惯用模式函数

2024-03-22

我正在学习 Clojure,想要一些关于惯用用法的建议。作为小型统计包的一部分,我有一个计算一组数据的众数的函数。 (背景:众数是一组数据中最常见的值。几乎有十几种已发布的算法来计算它。这里使用的算法来自 Bernard Rosner 的《生物统计学基础》第 6 版。)

(defn tally-map
 " Create a map where the keys are all of the unique elements in the input
   sequence and the values represent the number of times those elements
   occur. Note that the keys may not be formatted as conventional Clojure
   keys, i.e. a colon preceding a symbol."
  [aseq]
  (apply merge-with + (map (fn [x] {x 1}) aseq)))

(defn mode
 " Calculate the mode. Rosner p. 13. The mode is problematic in that it may
   not be unique and may not exist at all for a particular group of data.
   If there is a single unique mode, it is returned. If there are multiple
   modes, they are returned as a list. If there is no mode, that is all
   elements are present in equal frequency, nil is returned."
  [aseq]
  (let [amap (tally-map aseq)
        mx (apply max (vals amap))
        k (keys amap)
        f (fn [x] (not (nil? x)))
        modes (filter f (map #(if (= mx (get amap %)) %) k))
        ]
    (cond (= 1 (count modes)) (first modes)
      (every? #(= mx %) (vals amap)) nil
      :else modes)
    )
  )

我有几个问题:

  1. 论点。该函数接受单个序列。像加法函数这样接受可变数量的参数是否更惯用?
  2. 代码气味。看起来“let”比它应该的要复杂一些——这么多的变量赋值。我是否错过了语言或库的任何明显(或不那么明显)的用法,这些用法将使该方法更加简洁?

先谢谢您的帮助。


在我看来,将某些函数映射到集合上,然后立即将列表压缩为一项是一个使用的标志reduce.

(defn tally-map [coll]
  (reduce (fn [h n]
            (assoc h n (inc (h n 0))))
          {} coll))

在这种情况下我会写modefn 将单个集合作为参数,就像您所做的那样。我能想到对这样的函数使用多个参数的唯一原因是,如果您计划必须大量键入文字参数。

所以如果例如这是一个交互式 REPL 脚本,您经常会输入(mode [1 2 1 2 3])从字面上看,那么您应该让该函数接受多个参数,以免您输入额外的内容[]一直在函数调用中。如果您计划从文件中读取大量数字,然后采用这些数字的众数,则让该函数采用一个作为集合的参数,这样您就可以避免使用apply每时每刻。我猜你最常见的用例是后者。我相信apply还增加了当您有一个采用集合参数的函数调用时可以避免的开销。

我同意其他人的观点,你应该有mode即使只有一个结果,也返回结果列表;它会让你的生活更轻松。也许重命名它modes当你在做的时候。

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

Clojure 中的惯用模式函数 的相关文章

  • Clojure:生成所有键盘可输入字符

    Context 我想生成可以通过以下方式生成的所有字符 打开记事本 按键盘上的单个键 按住 Shift 按键盘上的单个键 我目前拥有的 concat range int a int z range int A int Z range int
  • 将向量作为绑定传递给 for 宏时出现问题

    我有任意数量的列表 我想使用 for 宏来处理它们 我想创建一个传递向量作为绑定的函数 因为列表的数量各不相同 如果我对绑定进行硬编码 它会按我的预期工作 gt def list1 pink green gt def list2 dog c
  • 使用 scipy、python、numpy 进行非线性 e^(-x) 回归

    下面的代码为我提供了一条最佳拟合线的平坦线 而不是沿着 e x 模型的一条适合数据的漂亮曲线 谁能告诉我如何修复下面的代码以使其适合我的数据 import numpy as np import matplotlib pyplot as pl
  • Clojure:让作用域和函数返回值

    我在弄清楚如何使用 let 形式时遇到了一些麻烦 在下面的示例中 我想在本地绑定值 cols 以便稍后在函数中处理它 然而 我注意到 如果我使用 let 函数 sel opt tmp 将返回 nil 值而不是列表 defn sel opt
  • Clojure 宏expand

    Why does macroexpand arm getHand getFinger 扩展到 arm getHand getFinger while macroexpand gt arm getHand getFinger 扩展到 getF
  • 高级描述熊猫

    有没有像 pandas 那样更高级的功能 通常我会继续这样 r pd DataFrame np random randn 1000 columns A r describe 我会得到一份很好的总结 就像这样 A count 1000 000
  • 改进迭代文本解析的 clojure lazy-seq 使用

    我正在编写一个 Clojure 实现这次编码挑战 http biostar stackexchange com questions 1759 code golf mean length of fasta sequences 尝试找出 Fas
  • R 中的卡方拟合优度检验

    我有一个观察值向量 还有一个用模型计算的值向量 actual lt c 1411 439 214 100 62 38 29 64 expected lt c 1425 3 399 5 201 6 116 9 72 2 46 3 30 4 6
  • 回归模型 statsmodel python

    这更多是一个统计问题 因为代码运行良好 但我正在学习 python 中的回归建模 我在下面使用 statsmodel 编写了一些代码来创建一个简单的线性回归模型 import statsmodels api as sm import num
  • 在 Clojure 中解压缩 zlib 流

    我有一个二进制文件 其内容由zlib compress在Python上 有没有一种简单的方法可以在Clojure中打开和解压缩它 import zlib import json with open data json zlib wb as
  • clojure 有 AES 库吗?

    clojure 有 AES 加密库吗 我应该使用通过 maven 或 clojars 提供的 java 库吗 感谢您的时间和考虑 下面是一个使用可用的 java 加密库的可能更惯用的示例 encrypt and decrypt这里每个都简单
  • NumPy 或 SciPy 计算加权中位数

    我正在尝试自动化 JMP 执行的流程 分析 gt 分布 输入 A 列作为 Y 值 使用后续列 作为 权重 值 在 JMP 中 您必须一次执行一列 我想使用 Python 循环所有列并创建一个数组 显示每列的中位数 例如 如果质量数组为 0
  • 经理游戏:如何计算市值?

    通常 足球经理游戏中的球员都有市场价值 经理们根据这些市场价值出售他们的球员 他们想 哦 这个球员值3 000 000 所以我会尝试以3 500 000的价格把他卖掉 所有球员都具备三个基本素质 强度值 1 99 他们所能达到的最大力量 1
  • 如何求真实数据的概率分布和参数? (Python 3)

    我有一个数据集来自sklearn我绘制了分布load diabetes target数据 即回归值load diabetes data用于预测 我使用它是因为它的回归变量 属性数量最少sklearn datasets 使用Python 3
  • C# SqlDataReader 执行统计信息和信息

    我正在创建一个自动数据库查询执行队列 这本质上意味着我正在创建一个 SQL 查询队列 这些查询将被一一执行 使用类似于以下的代码执行查询 using SqlConnection cn new SqlConnection Configurat
  • 将 R 中的时间数据绘制为各种分辨率(分钟、小时、秒等)

    我有一些 CSV 数据 例如 Timestamp Count 2009 07 20 16 30 45 10 2009 07 20 16 30 45 15 2009 07 20 16 30 46 8 2009 07 20 16 30 46 6
  • Java 中 .NET 的 Lambda 表达式

    我最近 再次 从 C 迁移到 Java 但我非常怀念 lambda 表达式和 C 的 IEnumerable Foreach 之类的东西 所以我正在寻找Java中的lambda表达式库 有比这更好的图书馆吗LambdaJ http code
  • Google Analytics 和哈希/锚点不起作用

    我希望你可以帮助我 我有一个 Javascript 画廊 每张图片都有一个特定的哈希值 www example com gallery html title 1 我的统计数据位于 Google Analytics 上 但即使我在相应的代码中
  • 如何计算加权平均值?

    我的语言是PHP 但是算法应该是相当通用的 我有一个关联数组 比方说 评级和评级次数 ratings array 1 gt 1 2 gt 3 3 gt 6 4 gt 3 5 gt 3 这相当于 1 2 2 2 3 3 3 3 3 3 4 4
  • Clojure MySQL 语法错误异常(“[...] 靠近 '???????????????' [...]”)

    除了建立连接之外 我在使用 clojure contrib sql 做任何事情时都遇到困难 我有一个 mysqld 在 localhost 3306 上运行 数据库名为clj db 用户 clj user localhost 和密码 clj

随机推荐