# Deleting integers that are sandwiched between symbols

I have a list of symbols and integers:

 lis  = {a, b, c, 1, d, e, 2, 3, f}


I'd like to delete each integer that is preceded and succeeded by a symbol:

  res = {a, b, c, d, e, 2, 3, f}

SequenceCases[lis, {a__Symbol, _Integer, b__Symbol} -> {a, b}]


...gives

{{a, b, c, d, e}}

• Take a look at SequenceReplace Commented May 28, 2018 at 22:03

Flatten[DeleteCases[SplitBy[lis, IntegerQ], {_Integer}]]
SequenceReplace[lis, {a_Symbol, _Integer, b_Symbol} -> Sequence[a, b]]
With[{s = ArrayPad[BlockMap[FreeQ[#, {_Symbol, _Integer, _Symbol}]&, lis, 3, 1], 1, True]}
Pick[lis,s]]


all give

{a, b, c, d, e, 2, 3, f}

• Yes, I missed the Sequence[a,b] in the second solution. Thank you. Commented May 28, 2018 at 23:19

ListCorrelate can be useful.

lis = {a, b, c, 1, d, e, 2, 3, f};

bin = Boole[IntegerQ /@ lis]

Pick[lis, Unitize[ListCorrelate[{1, 2, 4}, bin, 2] - 2], 1]

{0, 0, 0, 1, 0, 0, 1, 1, 0}

{a, b, c, d, e, 2, 3, f}


This is faster than either of the methods in kglr's answer that I am able to test in version 10.1:

lis = RandomChoice[{a, b, c, 1, d, e, 2, 3, f}, 150000];

With[{bin = Boole[IntegerQ /@ lis]},
Pick[lis, Unitize[ListCorrelate[{1, 2, 4}, bin, 2] - 2], 1]] //
Length // RepeatedTiming

Flatten[DeleteCases[SplitBy[lis, IntegerQ], {_Integer}]] // Length // RepeatedTiming

With[{s = ArrayPad[BlockMap[FreeQ[#, {_Symbol, _Integer, _Symbol}] &, lis, 3, 1], 1,
True]}, Pick[lis, s]] // Length // RepeatedTiming

{0.0556, 127770}

{0.136, 127770}

{0.1642, 127770}


Most of the time is spent on binarizing the list, so with a faster form for that:

With[{bin = Replace[lis, {_Integer -> 1, _ -> 0}, {1}]},
Pick[lis, Unitize[ListCorrelate[{1, 2, 4}, bin, 2] - 2], 1]] //
Length // RepeatedTiming

 {0.0219, 127770}

list = {a, b, c, 1, d, e, 2, 3, f, 9, g};


Using SequenceSplit (new in 11.3)

SequenceSplit[list, {a_Symbol, _Integer, b_Symbol} :> {a, b}] // Flatten


{a, b, c, d, e, 2, 3, f, g}

Using SequencePosition (new in 10.1)

SequencePosition[list, {a_Symbol, _Integer, _Symbol}] /. {a_Integer, _} :> {a}


{{3}, {9}}

Delete[%] @ list


{a, b, 1, d, e, 2, 3, 9, g}

lis = {a, b, c, 1, d, e, 2, 3, f, 5, h};


Using ReplaceRepeated:

lis //. {a___, b_Symbol, n_Integer , c_Symbol, d___} :> {a, b, c, d}

(*{a, b, c, d, e, 2, 3, f, h}*)


Or using SequenceCases and DeleteElements:

DeleteElements[#, SequenceCases[#, {a_Symbol, n_Integer, b_Symbol} :> n]] &@lis

(*{a, b, c, d, e, 2, 3, f, h}*)

list = {a, b, c, 1, d, e, 2, 3, f, 5, h};


Using DeleteElements (new in 13.1)

DeleteElements[
list,
Cases[Partition[list, 3, 1], {_Symbol, a_?NumberQ, _Symbol} :> a]]


{a, b, c, d, e, 2, 3, f, h}