我有一个列表列表,内部列表可能有可变长度。我需要根据内部列表元素的字母顺序对外部列表进行排序。例如,给出一个
列表 {{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 10, 0}, {0, 6, 2}, {5, 1, 2}, {0, 3, 6, 1, 4}}
我希望Sort
之后的输出为
{{0, 0, 10, 0}, {0, 0, 7}, {0, 3, 6, 1, 4}, {0, 6, 2}, {5, 0, 2, 3}, {5, 1, 2}}
我只是不知道如何处理内部列表的可变长度以编写比较函数。请帮忙。
修改
BTW,原始列表是数字列表。修改2
例如,我有一个列表:
{{0,0,7},{5,0,2,3},{0,0,11,0},{0,0,1,12},{0,6,2}, {5,1,2},{0,3,6,1,4}}
输出应为:
{{0,0,1,12},{0,0,11,0},{0,0,7},{0,3,6,1,4},{0,6,2 },{5,0,2,3},{5,1,2}}
原因是1
在词汇上小于11
,小于7
。
答案 0 :(得分:6)
您可以像这样设置lexciographic comparator:
lexComp[_, {}] := False;
lexComp[{}, _] := True;
lexComp[{a_, as___}, {b_, bs___}] := a < b || a == b && lexComp[{as}, {bs}];
然后,您可以使用它进行排序以获得所需的效果:
Sort[{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 10, 0}, {0, 6, 2}, {5, 1, 2}, {0, 3, 6, 1, 4}}, lexComp]
{{0, 0, 7}, {0, 0, 10, 0}, {0, 3, 6, 1, 4}, {0, 6, 2}, {5, 0, 2, 3}, {5, 1, 2}}
如果您希望将数字视为排序中的字符串,您可以这样修改:
lessAsString[a_, b_] := Order @@ (ToString /@ {a, b}) === 1;
olexComp[_, {}] := False;
olexComp[{}, _] := True;
olexComp[{a_, as___}, {b_, bs___}] := lessAsString[a, b] || a === b && olexComp[{as}, {bs}];
以下是这种类型的例子:
In[5]:= Sort[{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 11, 0}, {0, 0, 1, 12}, {0, 6, 2}, {5, 1, 2}, {0, 3, 6, 1, 4}}, olexComp]
Out[5]= {{0, 0, 1, 12}, {0, 0, 11, 0}, {0, 0, 7}, {0, 3, 6, 1, 4}, {0, 6, 2}, {5, 0, 2, 3}, {5, 1, 2}}
答案 1 :(得分:2)
alphaSort = #[[ Ordering @ Map[ToString, PadRight@#, {2}] ]] &;
这可以通过准备默认Ordering
排序的数据,然后使用该顺序对原始列表进行排序。
在这种情况下,将所有列表填充到相同的长度会使此Sort
属性不会受到干扰:
排序通常先将较短的表达式排序,然后以深度优先的方式比较各个部分。
ToString
用于获取字母顺序而非数字顺序。
答案 2 :(得分:1)
这应该这样做
{{0, 0, 7}, {5, 0, 2, 3}, {0, 0, 10, 0}, {0, 6, 2}, {5, 1, 2}, {0, 3,
6, 1, 4}} // SortBy[#, ToString] &
这是因为词汇,逗号和空格在数字之前,所以{a,b}在{a,b,c}之前是词法上的。