How to elegantly interleave two lists of uneven length in python?

前端 未结 8 1381
自闭症患者
自闭症患者 2021-01-04 06:13

I want to merge two lists in python, with the lists being of different lengths, so that the elements of the shorter list are as equally spaced within the final list as possi

相关标签:
8条回答
  • 2021-01-04 07:01

    Borrowing heavily from Jon Clements' solution, you could write a function that takes an arbitrary number of sequences and returns merged sequence of evenly-spaced items:

    import itertools as IT
    
    def evenly_spaced(*iterables):
        """
        >>> evenly_spaced(range(10), list('abc'))
        [0, 1, 'a', 2, 3, 4, 'b', 5, 6, 7, 'c', 8, 9]
        """
        return [item[1] for item in
                sorted(IT.chain.from_iterable(
                zip(IT.count(start=1.0 / (len(seq) + 1), 
                             step=1.0 / (len(seq) + 1)), seq)
                for seq in iterables))]
    
    iterables = [
        ['X']*2,
        range(1, 11),
        ['a']*3
        ]
    
    print(evenly_spaced(*iterables))
    

    yields

    [1, 2, 'a', 3, 'X', 4, 5, 'a', 6, 7, 'X', 8, 'a', 9, 10]
    
    0 讨论(0)
  • if a is the longer list and b is the shorter

    from itertools import groupby
    
    len_ab = len(a) + len(b)
    groups = groupby(((a[len(a)*i//len_ab], b[len(b)*i//len_ab]) for i in range(len_ab)),
                     key=lambda x:x[0])
    [j[i] for k,g in groups for i,j in enumerate(g)]
    

    eg

    >>> a = range(8)
    >>> b = list("abc")
    >>> len_ab = len(a) + len(b)
    >>> groups = groupby(((a[len(a)*i//len_ab], b[len(b)*i//len_ab]) for i in range(len_ab)), key=lambda x:x[0])
    >>> [j[i] for k,g in groups for i,j in enumerate(g)]
    [0, 'a', 1, 2, 'b', 3, 4, 5, 'c', 6, 7]
    

    You can use this trick to make sure a is longer than b

    b, a = sorted((a, b), key=len)
    
    0 讨论(0)
提交回复
热议问题