如何在 netlogo 中使用所有第 4 项嵌套列表的命令
How to use a command all the 4th item nested lists in netlogo
我构建了一个长嵌套列表,其配置文件如下:
set my-list [A 1 2 3 4] [B 5 6 7 8] [C 9 10 11 12]
我想将 mean
命令应用于每个嵌套列表的第四项,因此在示例中
4 8 12
但没有在循环中构建看起来像 [4 8 12]
的列表(以节省计算时间)。
可能吗?
使用 let comp mean (item i item 4 (my-list))
或 let comp mean (item 4 (my-list))
显然不起作用。
答案将对我正在构建的模型的其他部分有用。
感谢您的宝贵时间。
第一件事:你的意思是说这样的嵌套列表是像下面这样构建的吗?
set my-list [[A 1 2 3 4] [B 5 6 7 8] [C 9 10 11 12]]
注意额外的一对方括号,这实际上是一个列表列表。即使是这样,NetLogo 也不会让您使用该语法:
- 要么是因为A、B、C如果是字符串就没有引号;
- 或者因为,如果 A、B 和 C 是变量,NetLogo 需要文字值(我们可以使用
(list ...)
而不是 []
来解决这个问题)。
在第一种情况下,它必须是:
set my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
在第二种情况下,它必须是:
set my-list (list (list a 1 2 3 4) (list b 5 6 7 8) (list c 9 10 11 12))
以上所有只是为了确保我们都在同一页面上(一般来说,请确保您 post 在您的问题中使用的代码对您所询问的语言有效。作为你可以看到,它会节省很多时间和 space!)。
无论如何我想你想出的是这种类型的东西:
[["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
我会使用 while
循环遍历内部列表。您可以创建一个局部变量来跟踪您在遍历内部列表时提取的数字总和,然后将该总和除以您提取数字的次数:
to check-mean
let my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let the-sum 0
let i 0
while [i < length my-list] [
set the-sum (the-sum + item 4 (item i my-list))
set i i + 1
]
print the-sum / i
end
map
原语非常适合这类列表计算。它允许您为列表的每个部分单独执行报告,然后 returns 结果作为新列表。
let test-list [1 2 3]
show map [x -> x + 1] test-list
;> [2 3 4]
在您的情况下,您将使用 map 循环遍历列表列表,并使用 item
原语从每个子列表 (map [x -> item 4 x ] my-list
) 中提取必要的数字。然后 returns 他们作为一个列表,你可以取平均值。
to check-mean-2
let my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let my-mean mean map [x -> item 4 x ] my-list
print my-mean
end
编辑:虽然我的第一眼看上去效率更高,但 Matteo 的版本实际上运行得更快(至少在我的机器上)
globals [my-list]
to setup
set my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
end
to check-mean
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let the-sum 0
let i 0
while [i < length my-list] [
set the-sum (the-sum + item 4 (item i my-list))
set i i + 1
]
let my-mean the-sum / i
]
let the-timer timer ; ~0.207
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.210
end
to check-mean-2
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let my-mean mean map [x -> item 4 x ] my-list
]
let the-timer timer
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.235
end
另一个编辑:最后还有两个版本使用 reduce 而不是 map。版本 3 是其中最快的,但您应该注意 my-list 在此版本中添加了一个 0。这可能会使其他用途稍微不方便。您也可以在计算过程中将此 0 添加到其中,如版本 4 中所示,但这会再次增加时间。
to check-mean-3
set my-list [0 ["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let my-sum reduce [ [x y] -> x + item 4 y] my-list
let my-mean my-sum / (length my-list - 1)
]
let the-timer timer
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.170
end
to check-mean-4
set my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let my-new-list fput 0 my-list
let my-sum reduce [ [x y] -> x + item 4 y] my-new-list
let my-mean my-sum / (length my-list - 1)
]
let the-timer timer
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.226
end
根据上面的答案并在过程中添加一个步骤(列表中具有相同“区域”的项目组的平均值和标准差),here-below 是我使用 map
的最终代码因为 mean 和 sd 已经在 while-loop
中计算出来了。此外,我假设手动计算标准偏差会创建更多的列表列表并使代码复杂化。
to create-successor-list
set successor-list map [inner-list -> (list inner-list 0 0 ) ] region-data
let i 0
while [i < length region-data] [
let current-item item i region-data
set temp-profitability-list (filter [current-inner-list -> (item 1 current-inner-list = current-item)] profitability-list )
set prof-mean mean map [x -> item 4 x ] temp-profitability-list
set prof-sd standard-deviation map [x -> item 4 x ] temp-profitability-list
set successor-list replace-item i successor-list (replace-item 1 item i successor-list (prof-mean))
set successor-list replace-item i successor-list (replace-item 2 item i successor-list (prof-sd))
set i i + 1
set temp-profitability-list [ ]
]
end
我构建了一个长嵌套列表,其配置文件如下:
set my-list [A 1 2 3 4] [B 5 6 7 8] [C 9 10 11 12]
我想将 mean
命令应用于每个嵌套列表的第四项,因此在示例中
4 8 12
但没有在循环中构建看起来像 [4 8 12]
的列表(以节省计算时间)。
可能吗?
使用 let comp mean (item i item 4 (my-list))
或 let comp mean (item 4 (my-list))
显然不起作用。
答案将对我正在构建的模型的其他部分有用。
感谢您的宝贵时间。
第一件事:你的意思是说这样的嵌套列表是像下面这样构建的吗?
set my-list [[A 1 2 3 4] [B 5 6 7 8] [C 9 10 11 12]]
注意额外的一对方括号,这实际上是一个列表列表。即使是这样,NetLogo 也不会让您使用该语法:
- 要么是因为A、B、C如果是字符串就没有引号;
- 或者因为,如果 A、B 和 C 是变量,NetLogo 需要文字值(我们可以使用
(list ...)
而不是[]
来解决这个问题)。
在第一种情况下,它必须是:
set my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
在第二种情况下,它必须是:
set my-list (list (list a 1 2 3 4) (list b 5 6 7 8) (list c 9 10 11 12))
以上所有只是为了确保我们都在同一页面上(一般来说,请确保您 post 在您的问题中使用的代码对您所询问的语言有效。作为你可以看到,它会节省很多时间和 space!)。
无论如何我想你想出的是这种类型的东西:
[["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
我会使用 while
循环遍历内部列表。您可以创建一个局部变量来跟踪您在遍历内部列表时提取的数字总和,然后将该总和除以您提取数字的次数:
to check-mean
let my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let the-sum 0
let i 0
while [i < length my-list] [
set the-sum (the-sum + item 4 (item i my-list))
set i i + 1
]
print the-sum / i
end
map
原语非常适合这类列表计算。它允许您为列表的每个部分单独执行报告,然后 returns 结果作为新列表。
let test-list [1 2 3]
show map [x -> x + 1] test-list
;> [2 3 4]
在您的情况下,您将使用 map 循环遍历列表列表,并使用 item
原语从每个子列表 (map [x -> item 4 x ] my-list
) 中提取必要的数字。然后 returns 他们作为一个列表,你可以取平均值。
to check-mean-2
let my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let my-mean mean map [x -> item 4 x ] my-list
print my-mean
end
编辑:虽然我的第一眼看上去效率更高,但 Matteo 的版本实际上运行得更快(至少在我的机器上)
globals [my-list]
to setup
set my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
end
to check-mean
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let the-sum 0
let i 0
while [i < length my-list] [
set the-sum (the-sum + item 4 (item i my-list))
set i i + 1
]
let my-mean the-sum / i
]
let the-timer timer ; ~0.207
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.210
end
to check-mean-2
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let my-mean mean map [x -> item 4 x ] my-list
]
let the-timer timer
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.235
end
另一个编辑:最后还有两个版本使用 reduce 而不是 map。版本 3 是其中最快的,但您应该注意 my-list 在此版本中添加了一个 0。这可能会使其他用途稍微不方便。您也可以在计算过程中将此 0 添加到其中,如版本 4 中所示,但这会再次增加时间。
to check-mean-3
set my-list [0 ["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let my-sum reduce [ [x y] -> x + item 4 y] my-list
let my-mean my-sum / (length my-list - 1)
]
let the-timer timer
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.170
end
to check-mean-4
set my-list [["a" 1 2 3 4] ["b" 5 6 7 8] ["c" 9 10 11 12]]
let timer-list []
repeat 10 [
reset-timer
repeat 1000000 [
let my-new-list fput 0 my-list
let my-sum reduce [ [x y] -> x + item 4 y] my-new-list
let my-mean my-sum / (length my-list - 1)
]
let the-timer timer
show the-timer
set timer-list lput the-timer timer-list
]
show word "mean: " (mean timer-list) ; 0.226
end
根据上面的答案并在过程中添加一个步骤(列表中具有相同“区域”的项目组的平均值和标准差),here-below 是我使用 map
的最终代码因为 mean 和 sd 已经在 while-loop
中计算出来了。此外,我假设手动计算标准偏差会创建更多的列表列表并使代码复杂化。
to create-successor-list
set successor-list map [inner-list -> (list inner-list 0 0 ) ] region-data
let i 0
while [i < length region-data] [
let current-item item i region-data
set temp-profitability-list (filter [current-inner-list -> (item 1 current-inner-list = current-item)] profitability-list )
set prof-mean mean map [x -> item 4 x ] temp-profitability-list
set prof-sd standard-deviation map [x -> item 4 x ] temp-profitability-list
set successor-list replace-item i successor-list (replace-item 1 item i successor-list (prof-mean))
set successor-list replace-item i successor-list (replace-item 2 item i successor-list (prof-sd))
set i i + 1
set temp-profitability-list [ ]
]
end