1

如何使用列表理解将列表分成两半?

例如,如果我有[1,1,2,2,3,3,4,4,5,5] 并且我只想[1,1,2,2,3]

到目前为止我的尝试:

half mylist = [r | mylist!r ; r <- [0..(#mylist div 2)] ]    ||does not work

有什么想法吗?

[注:这实际上不是 Haskell,而是类似的。!用于索引列表,# 给出长度)

编辑::

好吧,事实证明

half mylist = [r | r <- [mylist!0..mylist!(#mylist div 2)] ]

有效,但仅在数字列表中而不是字符串中。有什么线索吗?

4

2 回答 2

8

这对于列表理解来说并不是一件合适的事情。列表推导是映射和过滤器(和 zip)的替代语法。拆分列表是折叠。

因此,您应该考虑另一种方法。例如

halve :: [a] -> [a]
halve [] = []
halve xs = take (n `div` 2) xs
    where n = length xs

在大型列表上拆分不是一个很好的操作,因为您首先获取长度(因此它始终是列表上的n + n/2操作。它更适合具有O(1)长度和拆分的类数组类型.

于 2012-05-05T17:52:43.647 回答
4

另一种可能的解决方案,使用布尔值守卫:

half xs = [x | (x,i) <- zip xs [1..], let m = length xs `div` 2, i <= m]

但正如唐斯图尔特所说,列表理解并不是这项工作的正确工具。

于 2012-05-05T18:24:00.203 回答