две операции со списками в математике

У меня есть две операции списка, которые я хотел бы попросить о помощи. То, как я их реализовал, не очень элегантно, поэтому я хочу поучиться у вас, знатоков.

1) Предположим, у меня есть два списка, один типа {{0,2,4},{1,3,2},{2,0,4}}, а другой {{1,3,7},{2,4,6},{3,1,9}}. Я хочу либо на основе значения, либо на основе какого-то критерия отфильтровать первый список, а затем получить соответствующие элементы во втором. Например, исходя из ненулевого значения, я хочу получить {{3,7},{2,4,6},{3,9}}. Исходя из условия больше 2, я хочу получить {{7},{4},{9}}.

2) У меня есть список типа {{{1,2},{1,1}},{{1,3},{2,4}},{{1,2},{2,3}},{{1,4},{3,3}}}. Я хочу сформировать {{{1,2},{{1,1},{2,3}}},{{1,3},{{2,4}}},{{1,4},{{3,3}}}. То есть я хочу сгруппировать эти вторые списки, если первый элемент тот же. Как я могу сделать это красиво?

Большое спасибо.


person Qiang Li    schedule 09.03.2011    source источник


Ответы (2)


Для первой части вам нужно Pick:

In[27]:= Pick[{{1,3,7},{2,4,6},{3,1,9}},{{0,2,4},{1,3,2},{2,0,4}},_?Positive]
Out[27]= {{3,7},{2,4,6},{3,9}}

In[28]:= Pick[{{1,3,7},{2,4,6},{3,1,9}},{{0,2,4},{1,3,2},{2,0,4}},_?(#>2&)]
Out[28]= {{7},{4},{9}}

Что касается второго вопроса, GatherBy поможет вам в этом:

In[29]:= x = GatherBy[{{{1, 2}, {1, 1}}, {{1, 3}, {2, 4}}, {{1, 2}, 
    {2, 3}}, {{1, 4}, {3, 3}}}, First]

Out[29]= {{{{1, 2}, {1, 1}}, {{1, 2}, {2, 3}}}, {{{1, 3}, 
    {2, 4}}}, {{{1, 4}, {3, 3}}}}

И затем вы можете применить правило, чтобы немного навести порядок:

In[30]:= x /. l:{{a_, _}..} :> {a, Last /@ l}

Out[30]= {{{1, 2}, {{1, 1}, {2, 3}}}, {{1, 3}, {{2, 4}}},
    {{1, 4}, {{3, 3}}}}
person Michael Pilat    schedule 09.03.2011
comment
+1. Спасибо. в первой части я думал о Pick. Но не позволяет мне поставить туда функцию (не то что Select), не так ли? Как вы относитесь к делу ›2? - person Qiang Li; 09.03.2011
comment
Я только что обновил свой ответ, вы можете использовать условие для шаблона в третьем аргументе. Я только что немного подчистил свой ответ на вторую часть... - person Michael Pilat; 09.03.2011
comment
@Qiang @Michael Даже если бы у Пика не было третьего аргумента, вы могли бы сделать это с Пиком следующим образом: Pick[{{1, 3, 7}, {2, 4, 6}, {3, 1, 9}}, Positive@{{0, 2, 4}, {1, 3, 2}, {2, 0, 4}}]. Вы можете использовать чистые функции в более сложных случаях. Обратите внимание, что вы можете использовать @ здесь, потому что Positive является Listable. Для неперечисляемых функций используйте Map на соответствующем уровне. - person Sjoerd C. de Vries; 09.03.2011

Как сказал Майкл, Pick определенно подходит для первого.

Для второй части я хотел бы предложить альтернативу, которая позволяет вам сделать это в одну строку: SelectEquivalents. (Знаю, скорее самореклама, но я часто использую эту функцию.) Чтобы получить результат, который вы ищете, просто введите

In[1] := SelectEquivalents[ <list>, First, Last, {#1,#2}& ]
Out[1]:= {{{1, 2}, {{1, 1}, {2, 3}}}, {{1, 3}, {{2, 4}}}, {{1, 4}, {{3, 3}}}}

Внутри SelectEquivalents использует Reap и Sow, поэтому First помечает каждый элемент в <list>, Last преобразует элемент в форму, которую мы хотим использовать, а {#1, #2}& возвращает список с элементами формы {Tag, {<items with that tag>}}. Преимущество в том, что вы можете указать все за один шаг и получить то, что хотите, без последующих преобразований.

person rcollyer    schedule 09.03.2011