List F#System.InvalidOperationException:集合已修改;枚举操作不能执行
我在F中遇到了这个问题# [不是C#那里已经有一篇类似的帖子,上面有类似的答案] 我理解在for循环中枚举字典时不可能修改它 我该怎么做呢List F#System.InvalidOperationException:集合已修改;枚举操作不能执行,list,dictionary,f#,List,Dictionary,F#,我在F中遇到了这个问题# [不是C#那里已经有一篇类似的帖子,上面有类似的答案] 我理解在for循环中枚举字典时不可能修改它 我该怎么做呢 let edgelist1 = [(1,2,3.0f);(1,2,4.0f);(5,6,7.0f);(5,6,8.0f)] let dict_edges = new Dictionary<int*int,(int*int*float32) list>() for x in edgelist1 do dict_edges.Add ((fun (a,
let edgelist1 = [(1,2,3.0f);(1,2,4.0f);(5,6,7.0f);(5,6,8.0f)]
let dict_edges = new Dictionary<int*int,(int*int*float32) list>()
for x in edgelist1 do dict_edges.Add ((fun (a,b,c)-> (a,b)) x, x)
for k in dict_edges.Keys do dict_edges.[k] <- (dict_edges.[k] |> List.rev)
let edgelist1=[(1,2,3.0f);(1,2,4.0f);(5,6,7.0f);(5,6,8.0f)]
让dict_edges=新字典()
对于edgelist1中的x,请指定edges.Add((乐趣(a,b,c)->(a,b))x,x)
对于k in dict_edges.Keys do dict_edges。[k]List.rev)
System.InvalidOperationException:集合已修改;列举
操作可能无法执行
在System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource)中
资源)在
System.Collections.Generic.Dictionary`2.KeyCollection.Enumerator.MoveNext()
地址:$FSI_0101.main@()
就个人而言,这是可行的
dict_edges.[(1,2)] <- dict_edges.[(1,2)] |> List.rev;;
dict_edges.[1,2]List.rev;;
在for循环中,我只需要更改字典值,而不是键
谢谢,说dict_edges=dict_edges.map($0.reverse())不是更容易吗
很抱歉f#语法不好只说dict_edges=dict_edges.map($0.reverse())不是更容易吗
很抱歉f#语法错误您可以将所有键复制到一个临时列表中,然后在修改原始词典时迭代该列表:
for k in (dict_edges.Keys |> Seq.toList) do
dict_edges.[k] <- (dict_edges.[k] |> List.rev)
用于k in(dict_edges.Keys |>Seq.toList)do
记录边缘。[k]列表版本)
但我强烈建议你重新考虑你的方法,消除原地突变。您现在面临的这个小问题只是基于突变的程序可能出现问题的第一次尝试。您可以将所有密钥复制到一个临时列表中,然后在修改原始词典的同时迭代该列表:
for k in (dict_edges.Keys |> Seq.toList) do
dict_edges.[k] <- (dict_edges.[k] |> List.rev)
用于k in(dict_edges.Keys |>Seq.toList)do
记录边缘。[k]列表版本)
但我强烈建议你重新考虑你的方法,消除原地突变。你现在面临的这个小问题只是一个基于变异的程序可能出现问题的第一次尝试。你发布的代码在语法上甚至都不正确,所以不清楚你到底想实现什么(编译器对着
((有趣的(a,b,c)-(a,b))x,x尖叫)
表示它希望第二个x
是一个列表)
我想你想要的是:你有一个加权边列表,节点之间可以有多条边。您希望将它们折叠成一个规范形式,其中所有连接任意一对节点的边都被分组(i,j)
。只需使用任何groupBy
库函数即可:
let map_edges =
edgelist1
|> List.groupBy (fun (a, b, _) -> (a, b))
|> Map.ofList
在当前代码中,您正在使用((fun(a,b,c)->(a,b))x,x)
提取元组的成员。相反,请在表达式的中使用模式:
for (a, b, c) in edgelist1 do dict_edges.Add ((a, b), [(a, b, c)])
(我已经添加了[]
,使它至少可以编译)
还要注意,您正在复制信息:您将节点元组存储在键和列表的值中,这使得数据结构可能不一致且更大。考虑以下事项:
let map_edges =
edgelist1
|> List.map (fun (a, b, c) -> (a, b), c)
|> List.groupBy fst
|> List.map (fun (nodeTuple, edgeList) ->
nodeTuple, (edgeList |> List.map snd))
|> Map.ofList
map_edges
|> Map.iter (fun (nodeI, nodeJ) edgeList ->
edgeList
|> Seq.map string
|> String.concat "; "
|> printfn "Nodes (%i, %i): weights %s" nodeI nodeJ
)
(您可能希望使用序列作为中间表示,而不是列表)您发布的代码在语法上甚至都不正确,因此不清楚您究竟想实现什么(编译器在((fun(a,b,c)->(a,b))x,x)
中尖叫,说它希望第二个x
是一个列表)
我想你想要的是:你有一个加权边列表,节点之间可以有多条边。您希望将它们折叠成一个规范形式,其中所有连接任意一对节点的边都被分组(i,j)
。只需使用任何groupBy
库函数即可:
let map_edges =
edgelist1
|> List.groupBy (fun (a, b, _) -> (a, b))
|> Map.ofList
在当前代码中,您正在使用((fun(a,b,c)->(a,b))x,x)
提取元组的成员。相反,请在表达式的中使用模式:
for (a, b, c) in edgelist1 do dict_edges.Add ((a, b), [(a, b, c)])
(我已经添加了[]
,使它至少可以编译)
还要注意,您正在复制信息:您将节点元组存储在键和列表的值中,这使得数据结构可能不一致且更大。考虑以下事项:
let map_edges =
edgelist1
|> List.map (fun (a, b, c) -> (a, b), c)
|> List.groupBy fst
|> List.map (fun (nodeTuple, edgeList) ->
nodeTuple, (edgeList |> List.map snd))
|> Map.ofList
map_edges
|> Map.iter (fun (nodeI, nodeJ) edgeList ->
edgeList
|> Seq.map string
|> String.concat "; "
|> printfn "Nodes (%i, %i): weights %s" nodeI nodeJ
)
(您可能希望使用序列作为中间表示,而不是列表)可能重复:可能重复:谢谢,我不知道列表。groupby,我自己重写了这个函数!谢谢,我不知道List.groupby,我自己重写了这个函数!