I have two lists of lists, La and Lb that I want to concatenate so that every element of a list n in La is concatenated with the corresponding element of list n in Lb. For example:

La = {{P, O, O, O}, {C, O, O, C, N}};

Lb = {{1, 2, 3, 4}, {9, 8, 7, 6, 5}};

with the desired result:

Lc = {{P1, O2, O3, O4}, {C9, O8, O7, C6, N5}};

I assume there is an easy way to do this, but I'm new to Mathematica.

  • 1
    $\begingroup$ Apply[StringJoin, Transpose /@ Transpose[{La, Lb}], {2}]... $\endgroup$
    – ciao
    Commented Jul 14, 2015 at 23:16
  • $\begingroup$ It is not clear if your input lists La and Lb contains already strings or symbols and numbers. Please edit your post to format properly the code part of your question. $\endgroup$
    – SquareOne
    Commented Jul 15, 2015 at 15:57

3 Answers 3


Here's an approach for any two multi-dimensional lists of strings which have arbitrary, but matching structures:

stringJoin[x__String] := StringJoin[x]
SetAttributes[stringJoin, Listable]
stringJoin[La, Lb]

Short explanation of listability:

Listable functions are effectively applied separately to each element in a list, or to corresponding elements in each list if there is more than one list.

In order to prevent premature evaluation of stringJoin[a,b] where a and b are lists, e.g. a = {a1,a2,a3}; b = {b1,b2,b3} leading to "a1a2a3b1b2b3" I have stringJoin accept only String arguments. Then it keeps drilling down to the lowest level until it finally does find a string.

Here's another example. Setting a function f to be listable is almost like replacing every occurrence of f[...] with Thread[f[...]].

list = {a, b, {c, d}, {e, f, g, h}, {i, j, k}}
f[list, list]
(* f[{a, b, {c, d}, {e, f, g, h}, {i, j, k}},
      {a, b, {c, d}, {e, f, g, h}, {i, j, k}}] *)


Thread[f[list, list]]

{f[a, a], f[b, b],
f[{c, d}, {c, d}], f[{e, f, g, h}, {e, f, g, h}], f[{i, j, k}, {i, j, k}]}

ReplaceRepeated can allow emulation of listability:

f[list, list] //. f[x_, y_] :> Thread[f[x, y]]
(* {f[a, a], f[b, b], {f[c, c], f[d, d]}, {f[e, e], f[f, f], f[g, g], f[h, h]}, {f[i, i], f[j, j], f[k, k]}} *)

Or we can simply do SetAttributes[f, Listable]; f[list, list].

  • $\begingroup$ Clever. +1 for out-of-the-box thinking. $\endgroup$
    – ciao
    Commented Jul 15, 2015 at 0:39
  • $\begingroup$ @ciao It's because every time I see a task like this and read the answers I'm already expecting a follow-up comment "but with La={{a,b,c,{d,e,f}},{g,h,i}} it doesn't work." Also the arrays in OP are ragged. $\endgroup$
    – LLlAMnYP
    Commented Jul 15, 2015 at 0:46
  • 1
    $\begingroup$ Well. I understand your concerns. But within its validity scope your answer is as elegant as they can go $\endgroup$ Commented Jul 15, 2015 at 1:45
  • 1
    $\begingroup$ @belisarius - agreed re: elegance, and LLlAMnYP: I hear you, few things irk me more than a question that gets answered with neat solutions only to have OP edit with "well, no, what I meant was... and it needs this and that too..." instead of providing that from the start. (n.b., I am not saying this question is one of those, just commenting on a shared frustration!) $\endgroup$
    – ciao
    Commented Jul 15, 2015 at 5:57
  • 1
    $\begingroup$ @ciao It's not even the fear of a follow-up question, it's just that I feel that a general solution has more lasting value to those, who might show up several months later and read it, then a solution that works in a very specific case. Maybe not OP, but another user will ask "what if I have more complex lists", but he won't have to make a new question - my answer will work for him too. Also I get more satisfaction out of solving a generalized problem, unless of course performance starts to suffer significantly. $\endgroup$
    – LLlAMnYP
    Commented Jul 15, 2015 at 13:54
sLa = Map[ToString, La, {2}];
sLb = Map[ToString, Lb, {2}];
MapThread[StringJoin, #] & /@ Transpose[{sLa, sLb}]


Thread[j @@ #] & /@ Transpose[{sLa, sLb}] /. j -> StringJoin

Since Plus already does the element-wise addition, you can do:

La + Lb /. Plus -> (List /* Map[ToString] /* StringJoin)

This assumes the elements won't be destroyed by the plus, but as described by LLlAMnYP you can just Listableize the function:

Function[{a, b}, StringJoin[ToString /@ {a, b}], Listable][La, Lb]

or ToString before the operation:

Plus @@ Map[ToString, {La, Lb}, {-1}];
% /. Plus -> StringJoin

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.