在Python中,有一种接受一个所谓的“切片”列表中的部分的便捷方式:
a = [1,2,3,4,5,6,7,8,9,10] # ≡ a = range(1,10)
a[:3] # get first 3 elements
a[3:] # get all elements except the first 3
a[:-3] # get all elements except the last 3
a[-3:] # get last 3 elements
a[3:7] # get 4 elements starting from 3rd (≡ from 3rd to 7th exclusive)
a[3:-3] # get all elements except the first 3 and the last 3
与播放clojure.repl/doc
Clojure中,我发现等同于所有的人,但我不知道他们是地道的。
(def a (take 10 (iterate inc 1)))
(take 3 a)
(drop 3 a)
(take (- (count a) 3) a)
(drop (- (count a) 3) a)
(drop 3 (take 7 a))
(drop 3 (take (- (count a) 3) a))
我的问题是:怎么给序列Clojure中? 换句话说,什么是返回一个序列的不同部分的正确方法是什么?
您可以简化使用所有那些count
通过take-last
还是drop-last
改为:
(def a (take 10 (iterate inc 1)))
(take 3 a) ; get first 3 elements
(drop 3 a) ; get all elements except the first 3
(drop-last 3 a) ; get all elements except the last 3
(take-last 3 a) ; get last 3 elements
(drop 3 (take 7 a)) ; get 4 elements starting from 3
(drop 3 (drop-last 3 a)) ; get all elements except the first and the last 3
而作为在下面的意见建议,你可以使用->>
宏“线程”几个一起操作。 例如,最后两行也可以写成这样:
(->> a (take 7) (drop 3)) ; get 4 elements starting from 3
(->> a (drop-last 3) (drop 3)) ; get all elements except the first and the last 3
我认为这两种方法都非常可读的,如果你只应用两个操作的列表,但是当你有长长的一串像take
, map
, filter
, drop
, first
再使用->>
宏可以使代码更容易阅读,甚至可能更容易编写。
序列的Python的概念是从Clojure的很大的不同。
在Python,
- 一个序列是一个有限有序集由非负数索引 ; 和
- 列表是一个可变的序列,您可以从添加切片或删除片。
在Clojure中,
- 一个序列是支持的接口
first
, rest
,和cons
; - 一个列表是不可变的有序集合以
cons
(或rest
)添加(或去除) first
元件(返回如此修改列表,反正)。
Clojure中的一个Python列表最近的东西是一个载体 。 正如亚当Sznajder建议 ,你可以使用切它subvec
,虽然你不能添加或删除片,你可以在Python。
subvec
是一种快速的固定时间操作,而drop
会让你付出绕过元素的数量( take
让你付出为你穿越元素,但这些都是你所感兴趣的那些)。
你的例子成为...
(def a (vec (range 1 (inc 10))))
(subvec a 0 3)
; [1 2 3]
(subvec a 3)
; [4 5 6 7 8 9 10]
(subvec a 0 (- (count a) 3))
; [1 2 3 4 5 6 7]
(subvec a (- (count a) 3))
; [8 9 10]
(subvec a 3 (+ 3 4))
; [4 5 6 7]
(subvec a 3 (- (count a) 3))
; [4 5 6 7]
还有一个功能subvec
。 不幸的是,它只能与载体的作品,所以你必须改变你的序列:
http://clojuredocs.org/clojure_core/clojure.core/subvec
切片序列是一个有点“代码味道”的 - 一般的顺序是专为项目的顺序访问。
如果你打算做了很多切片/级联的,也有更好的数据结构可用,尤其是结账的RRB树向量执行:
- https://github.com/clojure/core.rrb-vector
这支持非常有效subvec
和catvec
操作。