Commutative combination of elements of two lists

前端 未结 6 564
感动是毒
感动是毒 2021-01-15 14:13

Just a style question: Is there a build-in method to get the combinations under the assertion of commutative property and excluding elements paired with itself?



        
6条回答
  •  感动是毒
    2021-01-15 14:45

    I don't think this is the most self-explanatory way to do it so I wouldn't recommend it but I'll include it for completeness.

    Uses the fact that the commutative pairs are the upper and lower triangles of the matrix produced by the product of both arrays.

    The numpy function np.tril_indices returns a tuple containing the indices for only the lower-triangle of an array.

    1. Getting all products excluding commutative pairs (as you want) but including elements paired with itself (not what you want):
    >>> import numpy as np
    >>> n_vars = len(a)
    >>> assert len(b) == n_vars  # Only works if len(a) == len(b)
    >>> [(a[i], b[j]) for i, j in zip(*np.tril_indices(n_vars))]
    [('1', '1'), ('2', '1'), ('2', '2'), ('3', '1'), ('3', '2'), ('3', '3')]
    
    1. Excluding the elements paired with themselves (what you want):
    >>> [(a[i], b[j]) for i, j in zip(*np.tril_indices(n_vars, k=-1))]
    [('2', '1'), ('3', '1'), ('3', '2')]
    

    The k argument in np.tril_indices is an offset parameter so k=-1 means it doesn't include the diagonal terms.

    Since it's a numpy function it's probably very fast.

    1. If you convert a and b to numpy arrays you can also do this:
    >>> a = np.array(a)
    >>> b = np.array(b)
    >>> ind = np.tril_indices(n_vars, k=-1)
    >>> list(zip(a[ind[0]], b[ind[1]]))
    [('2', '1'), ('3', '1'), ('3', '2')]
    >>> np.stack([a[ind[0]], b[ind[1]]]).T
    array([['2', '1'],
           ['3', '1'],
           ['3', '2']], dtype='

提交回复
热议问题