def random_processor(M, N, L, qubit_yield, num_evil=0):
    """A utility function that generates a random :math:`C_{M,N,L}` missing some
    percentage of its qubits.

    INPUTS:
        M,N,L: the chimera parameters
        qubit_yield: ratio (0 <= qubit_yield <= 1) of #{qubits}/(2*M*N*L)
        num_evil: number of broken in-cell couplers between working qubits

    OUTPUT:
        proc (:class:`processor`): a :class:`processor` instance with a random
            collection of qubits and couplers as specified
    """
    # replacement for lambda in edge filter below that works with bot h
    def edge_filter(pq):
        # we have to unpack the (p,q) edge
        p, q = pq
        return q in qubits and p < q

    qubits = [(x, y, u, k) for x in range(M) for y in range(N) for u in [0, 1] for k in range(L)]
    nqubits = len(qubits)
    qubits = set(sample(qubits, int(nqubits * qubit_yield)))
    edges = ((p, q) for p in qubits for q in _chimera_neighbors(M, N, L, p))
    edges = list(filter(edge_filter, edges))
    possibly_evil_edges = [(p, q) for p, q in edges if p[:2] == q[:2]]
    num_evil = min(num_evil, len(possibly_evil_edges))
    evil_edges = sample(possibly_evil_edges, num_evil)
    return processor(set(edges) - set(evil_edges), M=M, N=N, L=L, linear=False)