Another way to do this using SubsetReplace
, Internal-CopyListStructure and ReplaceAll
:
Internal`CopyListStructure[list,
SubsetReplace[Flatten@list, {_Integer} -> s]] /. s -> Nothing
(*{f[3, 4], {{g[7, h[8, 9]]}}, {f[10]}}*)
Or the equivalent form:
F = Activate@
Internal`CopyListStructure[#,
SubsetReplace[Flatten@#, {_Integer} -> Inactive[Nothing]]] &;
F@list
(*{f[3, 4], {{g[7, h[8, 9]]}}, {f[10]}}*)
A generalization of @xzczd's answer is to find the heads of expressions that we don't want to remove using Cases
as follows:
patt = Alternatives @@ Blank /@ Union@Cases[#,
s : Except[_List | _Integer] :> Head[s], {0, ∞}] &@list
(*_f | _g | _h*)
list /. {_Integer :> Nothing, s : patt :> s}
(*{f[3, 4], {{g[7, h[8, 9]]}}, {f[10]}}*)
Another way, using Cases
and DeleteCases
:
exc = Cases[#, s : Except[_List | _Integer] :> s, {0, ∞}] &;
DeleteCases[#, Alternatives @@ Complement[Flatten@#, exc@#], Depth@#] &@list
(*{f[3, 4], {{g[7, h[8, 9]]}}, {f[10]}}*)