gpt4 book ai didi

通过谓词将列表过滤成两部分

转载 作者:太空宇宙 更新时间:2023-11-03 18:38:48 25 4
gpt4 key购买 nike

我想做

(filter-list-into-two-parts #'evenp '(1 2 3 4 5))
; => ((2 4) (1 3 5))

根据谓词的计算结果是否为真,列表被分成两个子列表。定义这样一个函数很容易:

(defun filter-list-into-two-parts (predicate list)
(list (remove-if-not predicate list) (remove-if predicate list)))

但我想知道 Lisp 中是否有内置函数可以执行此操作,或者是否有更好的编写此函数的方法?

最佳答案

我不认为有内置的,你的版本不是最优的,因为它遍历列表两次并对每个列表元素调用谓词两次。

(defun filter-list-into-two-parts (predicate list)
(loop for x in list
if (funcall predicate x) collect x into yes
else collect x into no
finally (return (values yes no))))

我返回两个值而不是它们的列表;这更符合习惯(您将使用 multiple-value-bind 从返回的多个值中提取 yesno,而不是使用 destructuring-bind 来解析列表,它包含更少,更快,另见 values function in Common Lisp )。

一个更通用的版本是

(defun split-list (key list &key (test 'eql))
(let ((ht (make-hash-table :test test)))
(dolist (x list ht)
(push x (gethash (funcall key x) ht '())))))
(split-list (lambda (x) (mod x 3)) (loop for i from 0 to 9 collect i))
==> #S(HASH-TABLE :TEST FASTHASH-EQL (2 . (8 5 2)) (1 . (7 4 1)) (0 . (9 6 3 0)))

关于通过谓词将列表过滤成两部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18116949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com