Efficient way to make subsets of list with placeholders

Depending on your Mma version:

{a, b, c, d} # & /@ Permutations[{1, 1, 0, 0}]

Or

<< Combinatorica`

{a, b, c, d} # & /@ Combinatorica`Permutations[{1, 1, 0, 0}]
(*{{a, b, 0, 0}, {a, 0, c, 0}, {a, 0, 0, d}, {0, b, c, 0}, {0, b, 0, d}, {0, 0, c, d}}*)

Not the smartest, but working:

GroupBy[
  Tuples@Thread[{lst, 0}],
  Count[0]
  ][2] (*here 2 is length @ lst - 2*)
{{a, b, 0, 0}, {a, 0, c, 0}, {a, 0, 0, d}, {0, b, c, 0}, {0, b, 0, d}, {0, 0, c, d}}

or

Function[lst,
 ReplacePart[0 lst, #] & /@ MapThread[
     Rule, Subsets[#, {2}] & /@ {Range@Length@lst, lst}, 2
 ]
]

The second method is 2000x times and MaxMemoryUsed is around 150KB in comparison to 500MB of the first one.


Normal@({a, b, c, d} SparseArray[ # -> 1 & /@ #, 4]) & /@ 
 Subsets[Range[4], {2}] 

{{a, b, 0, 0}, {a, 0, c, 0}, {a, 0, 0, d}, {0, b, c, 0}, {0, b, 0, d}, {0, 0, c, d}}