I have a list of expressions which are multiplications of different types of objects. The question is broadly about how I can look for a pattern an exact number of times and exclude patterns from the search.

I will start with an example list on which I am going to base my question:

lyst = {n1 * n2 * Pair[M[p1],M[s2]] * Pair[M[p3],M[s4]], n3 * n4 * Pair[M[p1],M[s2]] * Pair[M[p1],M[s2]], n5 * n6 * Pair[M[p1],M[s2]] }

Here, n1 - n4 are numbers and "Pair" and "M" are Heads that are defined in my program. Now what I would like to do is select all elements, in which the expression Pair[M[p1],M[s2]] appears exactly N times without objects whose head is 'Pair' appearing again (subsequently I also want to do this with other expressions but this is just to understand how I should tackle this problem).

Example: I would like to have a pattern test that looks for all elements in 'lyst' which contain Pair[M[p1],M[s2]] without the structure Pair[....] appearing again. In my example list that would just be the last element only, since it does contain this expression and 'Pair[...]' does not occur again.

I would be very thankful for suggestions on how to do this since I do not really have a good idea so far.

  • $\begingroup$ I edited the question. I hope it is better now. Thank you! $\endgroup$ May 16 at 11:51

1 Answer 1


Note, if Pair[M[p1],M[s2]] appears n times, it will be simplified to Pair[M[p1],M[s2]]^n. Therefore, the pattern to search must contain Pair[M[p1],M[s2]]^n. Further we must account for additional factors by "___" Here is an example with multiple items:

ex = {Times[n1, n2, Pair[M[p1], M[s2]]], 
   Times[n1, Pair[M[p1], M[s2]], Pair[M[p1], M[s2]], 
    Pair[M[p1], M[s2]]], 
   Times[n3, n4, Z[1], Pair[M[p1], M[s2]], Pair[M[p1], M[s2]]]} 

{n1 n2 Pair[M[p1], M[s2]], n1 Pair[M[p1], M[s2]]^3, 
 n3 n4 Pair[M[p1], M[s2]]^2}

For n==1:

Cases[ex, ___ Pair[M[p1], M[s2]]]

{n1 n2 Pair[M[p1], M[s2]]}

For N==2:

Cases[ex, ___ Pair[M[p1], M[s2]]^2]

{n3 n4 Pair[M[p1], M[s2]]^2}

For n==3:

Cases[ex, ___ Pair[M[p1], M[s2]]^3]

{n1 Pair[M[p1], M[s2]]^3}


If there are several different Pair[..] in the same element:

lyst = {n1*n2*Pair[M[p1], M[s2]]*Pair[M[p3], M[s4]], 
  n3*n4*Pair[M[p1], M[s2]]*Pair[M[p1], M[s2]], 
  n5*n6*Pair[M[p1], M[s2]]}

 HoldPattern[Except[___Pair] Pair[M[p1], M[s2]] Except[___Pair] ]]

{n5 n6 Pair[M[p1], M[s2]]}
  • $\begingroup$ Thanks! I realized that my first way of asking was a bit misleading so I edited the question. What you shows works great, but on top of that I want to make sure that the structure 'Pair[...]' does not appear again. To make this clear I updated my example list. It seems like a solution would be your code plus adding a test that makes sure that 'Pair[...]' does not appear again. Do you have a suggestion on that? $\endgroup$ May 16 at 12:00
  • $\begingroup$ If Pair[..] appears again, it will simplified to Pair[..]^(n+1) $\endgroup$ May 16 at 12:11
  • $\begingroup$ That is only true if the objects inside are the same. They are not always, as seen in my example. (e.g. I can also have 'Pair[M[p3],M[s4]]'). Then, the Pair - objects remain separated. $\endgroup$ May 16 at 12:12
  • $\begingroup$ Look what I have added. $\endgroup$ May 16 at 15:31
  • $\begingroup$ Awesome, thank you very much. I did not know I can combine HoldPattern and Except in this way. I have one question out of curiosity, because I can not understand the output: if I remove the second occurence of Except[___Pair] , i.e. if I write: Cases[lyst, HoldPattern[Except[___Pair] Pair[M[p1], M[s2]]]] , I would expect to get the same output since in the list all the appearances of 'Pair' are in the end. However, it just returns an empty list. Do you have an idea on why that is the case? $\endgroup$ May 17 at 15:42

Your Answer

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

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