将元素添加到列表末尾的正确方法是什么?

时间:2018-11-02 17:07:36

标签: list haskell

我在this Haskell页面上读到有关在List的末尾添加元素。

使用示例,我为自己进行了尝试。鉴于以下List,我想在其末尾添加数字56

示例:

let numbers = [4,8,15,16,23,42] 
numbers ++ [56]

我被this评论所吸引:

  

将项目添加到列表的末尾是一个很好的练习,但是通常   您不应该在真正的Haskell程序中这样做。很贵,而且   表示您以错误的顺序构建列表。有   通常是一种更好的方法。

Researching,我意识到我实际上在做的是创建一个List为唯一元素的56,并将其与numbers { {1}}。那是对的吗?

使用list正确的方法将元素添加到++的末尾吗?

2 个答案:

答案 0 :(得分:6)

++ [x]是将元素添加到列表末尾的正确方法,但是注释的意思是您不应该将元素添加到列表末尾。

由于定义列表的方式,总是在末尾添加元素需要复制列表。也就是说,

xs ++ ys

需要复制所有xs,但可以原样重复使用ys

如果xs仅是一个元素(即我们要添加到列表的开头),那没问题:复制一个元素几乎完全不需要时间。

但是如果xs更长,我们需要在++上花费更多的时间。

如果我们反复进行此操作(即通过不断向末尾添加元素来建立一个大列表),那么我们需要花费大量时间来制作冗余副本。 (以这种方式构建n元素列表是O(n 2 )操作。)

如果您需要这样做,通常可以使用一种更好的方法来构造算法。例如,您可以按相反的顺序构建列表(在开头添加元素),而在结尾仅调用reverse

答案 1 :(得分:5)

这是正确的方法,因为所有方法都必须减少到至少那么多的工作量。问题是根本想附加到列表的末尾。对于不可变的链表,这不是有效的操作。

更好的方法是弄清楚如何解决您的特定问题而不这样做。有很多潜在的方法。选择正确的选择取决于您正在执行的操作的细节。也许您可以只使用正确的懒惰就可以摆脱困境。也许最好是先反向生成列表,然后最后将其反向一次。也许您最好使用其他数据结构。这完全取决于您的特定用例。