# Complicated list slicing

Say I have a list with the structure

list = {{1, {x1, y1, z1}}, {2, {x2, y2, z2}}, {3, {x3, y3, z3}}, ...}


I would like to slice it such that I end up with

{{1, y1}, {2, y2}, ...}


Is there a clean way to do this with Part? Ie, something along the lines of

list[[All, {1,{2,2}}]]


(which clearly isn't the right levelspec syntax). But, for the life of me, I can't figure out how to slice it properly.

I know this is ultimately possible doing something like

Map[{#[[1]], #[[2, 2]]} &, list]


but this is a bit clumsy and I'm hoping there is a straight-forward list slice I can use instead. Not to mention, I clearly don't fully get how Mathematica implements Part, and I keep running around in circles on the help page.

list = {{1, {x1, y1, z1}}, {2, {x2, y2, z2}}, {3, {x3, y3, z3}}};


{#[[1]], #[[2, 2]]} & /@ list


You can use a number of additional methods, including

Transpose[{list[[All, 1]], list[[All, 2, 2]]}]
{#, #2[[2]]} & @@@ list
{#, #2 & @@ #2} & @@@ list
Transpose@Extract[Transpose[list], {{1}, {2, All, 2}}]
list2 = list; list2[[All, 2]] = list2[[All, 2, 2]]; list2
(* or, more simply, list[[All,2]]=list[[All,2,2]] if you want to modify the list *)
list3 = list; list3[[All, 2, 0]] = #2 &; list3


to get

{{1, y1}, {2, y2}, {3, y3}}

• Thanks! So I take it there isn't a way to get that slice just using Part? – Neal Pisenti Nov 14 '14 at 13:30
• @Neal, afaik not as of v10 :) Maybe someone more knowledgable could suggest a way to overload Part to accept an argument pattern like {1,{2,2}} (which, btw, is very natural, also the pattern i thought should work). – kglr Nov 14 '14 at 13:55
• I just wanted to clarify in the event you are brand new to Mathematica- in my mind, the first method kgular illustrated is pretty much only using part. The shorthand notation for part is [[x]]. It is true that technically, he is also using list {} and map /@ to get your desired solution, but this is a very typical way of doing list manipulation in Mathematica. I don't see Wolfram ever adding on to the Part function so that you only have to use part in place of the aforementioned method. @kguler, +1 for the answer! – tjm167us Nov 14 '14 at 14:06

I find extracting the parts and then combining them (e.g. with Transpose) to be fast and general. kguler already showed this but again for reference:

{list[[All, 1]], list[[All, 2, 2]]}\[Transpose]

{{1, y1}, {2, y2}, {3, y3}}


Pattern matching is another general method, though often not quite as fast.

Cases[list, {a_, b_} :> {a, b[[2]]}]

{{1, y1}, {2, y2}, {3, y3}}


Since your example only requires modification of the {x1, y1, z1} part you could also use MapAt:

MapAt[#[[2]] &, list, {All, 2}]

{{1, y1}, {2, y2}, {3, y3}}


Using Replace

list /. {a_, b_List} :> {a, b[[2]]}


or

Replace[list, a_List :> a[[2]], {2}]


{{1, y1}, {2, y2}, {3, y3}}

Mapping Thread on the list is useful in a lot of such cases:

(Thread /@ list)[[All, 2]]

(* {{1, y1}, {2, y2}, {3, y3}} *)


Another method

list // Thread[{#[[All, 1]], #[[All, 2, 2]]}] &


{{1, y1}, {2, y2}, {3, y3}}