我使用mathematica 7,我试图使用一个单链接列表(~50,000个元素)来避免在动态列表中使用AppendTo来提高速度。在这个测试中,我可以创建一个包含10个元素的列表,如下所示
list1 = Fold[{#1, #2} &, {}, RandomInteger[10^5, 10]]
我试着像这样用Part
访问它(访问一个随机元素100次)
Timing[list1[[Sequence @@ ConstantArray[1, #], 2]] & /@RandomInteger[{1,10}, 100]]
对于小型列表(如上面所示的10),这很好。由于我不明白的原因,当列表中有更多的元素(如10^4)时,这会扼杀内核。我试过在这个网站上四处看看&其他地方,但我只是不知道我应该如何使用链接列表。我甚至尝试过使用不同的实现,如f[e1,f[e2,f[e3,...f[]...]]]
,但在使用此方案时,我不知道如何访问和操作元素。我想问题必须做w/ $RecursionLimit
,但我不知道如何绕过它。
特别是我希望能用
list1[[Sequence @@ ConstantArray[1, index], 2]] = new value
在我的密码里。同样,当列表很小时,这也是可行的,但是对于更大的列表,内核最终会崩溃。奇怪的是,内核并不总是崩溃,而只是随机地处理大型列表。这听起来类似于here on SE描述的内容,但我不知道这种讨论是否相关。真的,我只是在修改LL元素方面需要帮助&在mathematica中正确地使用LL。
提前谢谢。
发布于 2012-12-08 04:14:30
我可以确认崩溃,但只有使用更深层次的Part
规范:
n = 5000000;
list1 = Fold[List, {}, RandomInteger[10^5, n]];
Do[
list1[[Sequence @@ ConstantArray[1, i], 2]] = "token"; Print[i],
{i, 100000, 200000, 10000}
]
100000 110000 120000 130000 140000 150000 160000 170000
因此,在我的系统中,坠机的深度超过17万。它也发生了,至少在这个深度,只有在分配一个部分时,而不仅仅是提取一个:
Timing[
list1[[##, 2]] & @@ ConstantArray[1, #] & /@ RandomInteger[{1, n - 1}, 10]
]
{1.03,{77041,74008,29990,13286,12762,48702,76027,25009,31267,1887}
推荐
作为另一种选择,我建议使用 functions。
n = 5000000;
list2 = Internal`Bag @ RandomInteger[10^5, n]; (* fill our Bag *)
Internal`StuffBag[list2, 27182]; (* add an element to the Bag *)
Internal`BagLength @ list2 (* check the length of our Bag *)
5000001
pos = RandomInteger[{1, n}, 10]; (* pick ten random positions *)
(* assign to those positions values 1 through 10 *)
MapIndexed[
(Internal`BagPart[list2, #] = #2[[1]]) &,
pos
];
Internal`BagPart[list2, pos] (* check the contents of those positions *)
{1、2、3、4、5、6、7、8、9、10}
(* convert our Bag into a standard list *)
flat = Internal`BagPart[list2, All];
flat[[pos]] (* check the contents again *)
{1、2、3、4、5、6、7、8、9、10}
Last @ flat (* check that the element we appended is still there *)
27182
https://stackoverflow.com/questions/13775274
复制相似问题