What is the correct way to pattern match nested lists?

I have the following function:

f[lst_List /; MatchQ[lst, SOME PATTERN HERE]] :=
({#[[1]] + #[[2]], #[[1]] - #[[2]]} &) /@ lst;


I want to match lists that are ordered pairs of reals: {{0.1, 0.2}, {0.3, 0.4}}, and so on. I tried the following pattern:

MatchQ[{{0.1, 0.2},{0.3, 0.4}}, _List[_List[_Real, _Real]]]


but this returned False. I know that:

MatchQ[{{0.1, 0.2},{0.3, 0.4}}, {__List}]


returns True, but this pattern is not sufficiently specific, since it also matches {{}}, among others.

What is the correct way to construct the pattern I want?

• MatchQ[{{0.1, 0.2}, {0.3, 0.4}}, List[List[_?NumericQ, _?NumericQ] ..]] ? Commented May 5, 2014 at 23:05
• MatchQ[{{0.1, 0.2}, {0.3, 0.4}}, {{Except[_Complex], Except[_Complex]} ..}]
– ciao
Commented May 5, 2014 at 23:06
• Thank you very much. They work. Commented May 5, 2014 at 23:17

There is no need to explicitly refer to MatchQ. Mathematica's pattern language is up to expressing what you want as an argument pattern.

f[lst : {{Repeated[Except[_Complex, _?NumberQ], {2}]} ..}] :=
({#[[1]] + #[[2]], #[[1]] - #[[2]]}&) /@ lst
f @ {{0.1, 0.2}, {0.3, 0.4}, {1/2, 1}, {2, 2.}}

{{0.3, -0.1}, {0.7, -0.1}, {3/2, -(1/2)}, {4., 0.}}


The function does not evaluate for lists containing pairs having a complex component.

f @ {{1, 1}, {1, I}}

f[{{1, 1}, {1, I}}]


It is not defined in the question what you wish to consider "real" for the purpose of this pattern. Is Pi real for your purposes for example? If you want to match only explicit decimal values you should use _Real, e.g. {{_Real, _Real} ..}. If you want something more general I propose:

realQ = Re[#] == # &;


Because Re is Listable this can be applied to arrays, allowing:

f[lst : {{_, _} ..}?realQ] := (* body *)


This is clear, concise, and has lower overhead than what m_goldberg proposed.

• Thank you very much for this explanation. Commented Jul 9, 2014 at 7:53