Select sub-sequences in lists?
I was expecting mathematica to also be able to access the fields in place without writing a new list
In-place modification approach:
list = {{a1, {b1, c1}}, {a2, {b2, c2}}, {a3, {b3, c3}}};
list[[;; , 2]] = list[[;; , 2, 2]];
list
{{a1, c1}, {a2, c2}, {a3, c3}}
Other solutions
MapAt[Last, list, {All, 2}]
(* {{a1, c1}, {a2, c2}, {a3, c3}} *)
list /. {x_, {y_, z_}} -> {x, z}
(* {{a1, c1}, {a2, c2}, {a3, c3}} *)
Benchmark
Large data, 10^7 lines.
largeList =
Table[{RandomReal[1], {RandomReal[1], RandomReal[1]}}, {10^7}];
First
@
AbsoluteTiming
returns the absolute number of seconds in real time that have elapsed during evaluation.
First@AbsoluteTiming[
MapAt[Last, largeList, {All, 2}]
]
(* 4.86435 *)
First@AbsoluteTiming[
largeList /. {x_, {y_, z_}} -> {x, z}
]
(* 4.95776 *)
First@AbsoluteTiming[
Partition[Flatten@largeList, 3][[All, {1, 3}]]
]
(* 3.66688 *)
First@AbsoluteTiming[
{#, #2[[-1]]} & @@@ largeList
]
(* 8.83799 *)
First@AbsoluteTiming[
{#[[1]], #[[2, -1]]} & /@ largeList
]
(* 12.3966 *)
First@AbsoluteTiming[
Module[{modlist = largeList}
, modlist[[;; , 2]] = modlist[[;; , 2, 2]]
]
]
(* 2.6865 *)
First@AbsoluteTiming[
Query[All, {1 -> Identity, 2 -> Last}]@largeList
]
(* 23.1379 *)
First@AbsoluteTiming[
{#, #2 & @@ #2} & @@@ largeList
]
(* 12.7286 *)
First@AbsoluteTiming[
{#[[1]], #[[2, 2]]} & /@ largeList
]
(* 13.2996 *)
First@AbsoluteTiming[
largeList[[;; , 2]] = largeList[[;; , 2, 2]]
]
(* 2.07737 *)
Update: Using a slightly modified version of the list of parts:
list = {{a1, {b1, c1}}, {a2, {b2, c2}}, {a3, {b3, c3}}};
parts = {{1}, {2, 2}};
list2 = {{d1, e1}, {d2, e2}, {d3, e3}};
Do[(list[[i, ##]] = list2[[i, #]]) & @@@ parts, {i, Length @ list2}]
list
{{d1, {b1, e1}}, {d2, {b2, e2}}, {d3, {b3, e3}}}
Alternatively, you can use ReplacePart
:
list = {{a1, {b1, c1}}, {a2, {b2, c2}}, {a3, {b3, c3}}};
list = ReplacePart[list, ({i_, ##} :> list2[[i, #]]) & @@@ parts];
list
{{d1, {b1, e1}}, {d2, {b2, e2}}, {d3, {b3, e3}}}
Original answer:
Few additional alternatives:
Transpose@{list[[All, 1]], list[[All, 2, 2]]}
Cases[list , {a_, {b_, c_}} :> {a, c}]
Replace[list , {_, b_} :> b, {2}]
Query[All, {1 -> Identity, 2 -> Last}] @ list
{#, #2 & @@ #2} & @@@ list
{#, #2[[-1]]} & @@@ list
{#[[1]], #[[2, 2]]} & /@ list
all give
{{a1, c1}, {a2, c2}, {a3, c3}}