以功能样式创建列表映射的有效方法

Mic*_*ahl 3 f#

给定数据集,例如可能如下所示的CSV文件:

x,y
1,2
1,5
2,1
2,2
1,1
...
Run Code Online (Sandbox Code Playgroud)

我希望创建一个包含给定x的y的列表映射...结果可能如下所示:

{1:[2,5,1], 2:[1,2]}
Run Code Online (Sandbox Code Playgroud)

在python中,这将是一种迫切的方式直接做...并且可能看起来像这样:

d = defaultdict(list)
for x,y in csv_data:
    d[x].append(y)
Run Code Online (Sandbox Code Playgroud)

你将如何使用F#中的函数编程技术实现相同的目标? 是否有可能像在给定的python示例中一样使用简单(和可读),只使用功能样式?,或者你必须回归到具有可变数据结构的命令式编程风格.?

注意:这不是一个家庭作业,只是我试图围绕功能编程

编辑:我的结论基于迄今为止的答案

我尝试在一个相对较大的csv文件上计算每个提供的答案,只是为了获得性能的感觉.此外,我用命令式方法做了一个小测试:

let res = new Dictionary<string, List<string>>()
for row in l do
    if (res.ContainsKey(fst row) = false) then 
        res.[fst row] <- new List<string>()
    res.[fst row].Add(snd row)
Run Code Online (Sandbox Code Playgroud)

命令式方法在约0.34秒内完成.

我认为李提供的答案是最普遍的FP,但运行时间约为4秒.

丹尼尔给出的答案在约1.55秒内完成.

最后,jbtule给出的答案大约是0.26.(我发现它击败了强制性的方法非常有趣)

我使用'System.Diagnostics.Stopwatch()'进行计时,代码在.Net 4.5中作为F#3.0执行

EDIT2:修复了命令式f#代码中的愚蠢错误,并确保它使用与其他解决方案相同的列表

Dan*_*iel 7

[
  1,2
  1,5
  2,1
  2,2
  1,1
]
|> Seq.groupBy fst
|> Seq.map (fun (x, ys) -> x, [for _, y in ys -> y])
|> Map.ofSeq
Run Code Online (Sandbox Code Playgroud)