Maxima:如何滚动(或移动)列表
Maxima: how to roll (or shift) a list
滚动列表的最简单方法是什么?
考虑以下列表:
myList : [0,1,4,6,3]
我正在寻找一个 roll()
函数,可以:
(%i0) roll(myList,1)
(%o0) [3,0,1,4,6]
(%i1) roll(myList,-1)
(%o1) [1,4,6,3,0]
我可以通过调用获得相同的结果:
myItem : pop(myList)
myList : append(myList,myItem)
问题是这仅在一个方向上有效(据我所知没有 pop_back()
功能 (?))并且它是两个衬垫。有更好的方法吗?
嗯,没有内置函数。但我认为你可以使用 rest
来获得你想要的效果。
(%i10) rotate (e, n) :=
if atom(e) then e
else block ([a : args(e)],
apply (op(e),
append (rest (a, length(a) - n), rest (a, -n)))) $
(%i11) foo : [a, b, c, d, e, f, g];
(%o11) [a, b, c, d, e, f, g]
(%i12) rotate (foo, 2);
(%o12) [f, g, a, b, c, d, e]
(%i13) rotate (foo, 7);
(%o13) [a, b, c, d, e, f, g]
这适用于所有表达式,而不仅仅是列表。
(%i16) rotate (f(1,2,3), 2);
(%o16) f(2, 3, 1)
此实现不接受大于参数数量的负数 n
或 n
,尽管我认为这很容易处理。
我假设 rotate
将较小索引处的元素移动到较大索引中。同样,如果您希望默认值朝另一个方向移动,我认为这样做很容易。
编辑:实际上没有必要分开op(e)
和args(e)
。当 e
不是列表并且它做正确的事情时,您可以调用 rest(e, ...)
。所以更简洁的版本是:
rotate (e, n) :=
if atom(e) then e
else append (rest (e, length(e) - n), rest (e, -n)) $
滚动列表的最简单方法是什么?
考虑以下列表:
myList : [0,1,4,6,3]
我正在寻找一个 roll()
函数,可以:
(%i0) roll(myList,1)
(%o0) [3,0,1,4,6]
(%i1) roll(myList,-1)
(%o1) [1,4,6,3,0]
我可以通过调用获得相同的结果:
myItem : pop(myList)
myList : append(myList,myItem)
问题是这仅在一个方向上有效(据我所知没有 pop_back()
功能 (?))并且它是两个衬垫。有更好的方法吗?
嗯,没有内置函数。但我认为你可以使用 rest
来获得你想要的效果。
(%i10) rotate (e, n) :=
if atom(e) then e
else block ([a : args(e)],
apply (op(e),
append (rest (a, length(a) - n), rest (a, -n)))) $
(%i11) foo : [a, b, c, d, e, f, g];
(%o11) [a, b, c, d, e, f, g]
(%i12) rotate (foo, 2);
(%o12) [f, g, a, b, c, d, e]
(%i13) rotate (foo, 7);
(%o13) [a, b, c, d, e, f, g]
这适用于所有表达式,而不仅仅是列表。
(%i16) rotate (f(1,2,3), 2);
(%o16) f(2, 3, 1)
此实现不接受大于参数数量的负数 n
或 n
,尽管我认为这很容易处理。
我假设 rotate
将较小索引处的元素移动到较大索引中。同样,如果您希望默认值朝另一个方向移动,我认为这样做很容易。
编辑:实际上没有必要分开op(e)
和args(e)
。当 e
不是列表并且它做正确的事情时,您可以调用 rest(e, ...)
。所以更简洁的版本是:
rotate (e, n) :=
if atom(e) then e
else append (rest (e, length(e) - n), rest (e, -n)) $