给定数据集,例如可能如下所示的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#代码中的愚蠢错误,并确保它使用与其他解决方案相同的列表
[
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)
| 归档时间: |
|
| 查看次数: |
1501 次 |
| 最近记录: |