How would you generate a list comprising n [1] values and k-n [0] values as compactly as possible (1) without shallow copying within the results and (2) without using list comprehensions? (The hard part of this question is that the elements of the list are lists; if they were immutable types such as numbers the multiplication solution would work, because copying the template would make deep copies.)

Here are three solutions:

def list_mult(n,k):
    return([[1]]*n+[[0]]*(k-n))
def list_comp(n,k):   
    return([[1] for i in range(n)] + [[0] for i in range(k-n)])
def list_for(n,k):
   res = []
   for i in range(n):
      i+=[1]
   for i in range(k-n):
      i+=[0]
   return(res)

Maybe this is an unfair set of constraints; in other words, the answer might be “list comprehensions are the right way to do this, get over it, or write a utility module that encapsulates list_for and import it so you don’t have to see the complexity”

Another possible solution would be to use lists of tuples instead of lists of lists, since tuples are immutable.

def list_tuple(n,k):
    return([(1,)]*n+[(0,)]*(k-n) )

The only downside I see of this is that the syntax of [(1,)] is a little bit inscrutable (“make a list containing a single element which is a single-element tuple containing 1”) – starts to approach code golf. Maybe this is just because single-element tuples look weird (they have to, because (1) would be indistinguishable from a parenthesized number).