복붙노트

[PYTHON] 교대로 두 목록을 결합하는 Pythonic 방식?

PYTHON

교대로 두 목록을 결합하는 Pythonic 방식?

나는 두 개의 목록을 가지고 있는데, 첫 번째 목록은 두 번째 목록보다 정확히 하나 더 많은 항목을 포함하도록 보장됩니다. 짝수 인덱스 값이 첫 번째 목록에서오고 홀수 인덱스 값이 두 번째 목록에서 오는 새 목록을 만드는 가장 Pythonic 한 방법을 알고 싶습니다.

# example inputs
list1 = ['f', 'o', 'o']
list2 = ['hello', 'world']

# desired output
['f', 'hello', 'o', 'world', 'o']

이 방법은 효과가 있지만 예쁜 것은 아닙니다.

list3 = []
while True:
    try:
        list3.append(list1.pop(0))
        list3.append(list2.pop(0))
    except IndexError:
        break

어떻게이 일을 성취 할 수 있습니까? 가장 Pythonic 한 접근 방식은 무엇입니까?

해결법

  1. ==============================

    1.다음은 슬라이스로이를 수행하는 한 가지 방법입니다.

    다음은 슬라이스로이를 수행하는 한 가지 방법입니다.

    >>> list1 = ['f', 'o', 'o']
    >>> list2 = ['hello', 'world']
    >>> result = [None]*(len(list1)+len(list2))
    >>> result[::2] = list1
    >>> result[1::2] = list2
    >>> result
    ['f', 'hello', 'o', 'world', 'o']
    
  2. ==============================

    2.itertools 문서에는 다음과 같은 제조법이 있습니다.

    itertools 문서에는 다음과 같은 제조법이 있습니다.

    from itertools import cycle, islice
    
    def roundrobin(*iterables):
        "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
        # Recipe credited to George Sakkis
        pending = len(iterables)
        nexts = cycle(iter(it).next for it in iterables)
        while pending:
            try:
                for next in nexts:
                    yield next()
            except StopIteration:
                pending -= 1
                nexts = cycle(islice(nexts, pending))
    
  3. ==============================

    3.이것은 당신이 원하는 것을해야합니다 :

    이것은 당신이 원하는 것을해야합니다 :

    >>> iters = [iter(list1), iter(list2)]
    >>> print list(it.next() for it in itertools.cycle(iters))
    ['f', 'hello', 'o', 'world', 'o']
    
  4. ==============================

    4.

    import itertools
    print [x for x in itertools.chain.from_iterable(itertools.izip_longest(list1,list2)) if x]
    

    나는 이것이 가장 평범한 방법이라고 생각한다.

  5. ==============================

    5.itertools가없고 l1이 l2보다 1 항목 길다는 가정하에 :

    itertools가없고 l1이 l2보다 1 항목 길다는 가정하에 :

    >>> sum(zip(l1, l2+[0]), ())[:-1]
    ('f', 'hello', 'o', 'world', 'o')
    

    itertools를 사용하고리스트에 None이 없다고 가정하면 :

    >>> filter(None, sum(itertools.izip_longest(l1, l2), ()))
    ('f', 'hello', 'o', 'world', 'o')
    
  6. ==============================

    6.나는 하나의 항목이 다른 것보다 더 많은 두 목록에 대해 묻는 질문을 알고 있지만 나는이 질문을 찾을 수있는 다른 사람들을 위해 이것을 넣을 것이라고 생각했다.

    나는 하나의 항목이 다른 것보다 더 많은 두 목록에 대해 묻는 질문을 알고 있지만 나는이 질문을 찾을 수있는 다른 사람들을 위해 이것을 넣을 것이라고 생각했다.

    Duncan의 솔루션은 크기가 다른 두 개의 목록으로 작업하도록되어 있습니다.

    list1 = ['f', 'o', 'o', 'b', 'a', 'r']
    list2 = ['hello', 'world']
    num = min(len(list1), len(list2))
    result = [None]*(num*2)
    result[::2] = list1[:num]
    result[1::2] = list2[:num]
    result.extend(list1[num:])
    result.extend(list2[num:])
    result
    

    이 결과는 다음과 같습니다.

    ['f', 'hello', 'o', 'world', 'o', 'b', 'a', 'r'] 
    
  7. ==============================

    7.하나의 라이너가 있습니다.

    하나의 라이너가 있습니다.

    list3 = [쌍의 항목에 대한 zip (list1, list2 + [0]) 쌍의 항목 [] - 1]

  8. ==============================

    8.이것은 Carlos Valiente의 위의 기고 물을 기반으로합니다. 여러 항목의 그룹을 대체하고 모든 항목이 출력에 있는지 확인하는 옵션이 있습니다.

    이것은 Carlos Valiente의 위의 기고 물을 기반으로합니다. 여러 항목의 그룹을 대체하고 모든 항목이 출력에 있는지 확인하는 옵션이 있습니다.

    A=["a","b","c","d"]
    B=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
    
    def cyclemix(xs, ys, n=1):
        for p in range(0,int((len(ys)+len(xs))/n)):
            for g in range(0,min(len(ys),n)):
                yield ys[0]
                ys.append(ys.pop(0))
            for g in range(0,min(len(xs),n)):
                yield xs[0]
                xs.append(xs.pop(0))
    
    print [x for x in cyclemix(A, B, 3)]
    

    이렇게하면 목록 A와 B가 각각 3 개의 값으로 그룹화됩니다.

    ['a', 'b', 'c', 1, 2, 3, 'd', 'a', 'b', 4, 5, 6, 'c', 'd', 'a', 7, 8, 9, 'b', 'c', 'd', 10, 11, 12, 'a', 'b', 'c', 13, 14, 15]
    
  9. ==============================

    9.나의 테이크 :

    나의 테이크 :

    a = "hlowrd"
    b = "el ol"
    
    def func(xs, ys):
        ys = iter(ys)
        for x in xs:
            yield x
            yield ys.next()
    
    print [x for x in func(a, b)]
    
  10. ==============================

    10.

    def combine(list1, list2):
        lst = []
        len1 = len(list1)
        len2 = len(list2)
    
        for index in range( max(len1, len2) ):
            if index+1 <= len1:
                lst += [list1[index]]
    
            if index+1 <= len2:
                lst += [list2[index]]
    
        return lst
    
  11. ==============================

    11.조금 더 늦은 구매가 될 수도 있고 파이썬 한 줄짜리 다른 라이너 일 수도 있습니다. 두 목록의 크기가 동일하거나 같지 않으면이 방법이 효과적입니다. 아무것도 가치가없는 한 가지는 a와 b를 수정할 것입니다. 문제가 있다면 다른 솔루션을 사용해야합니다.

    조금 더 늦은 구매가 될 수도 있고 파이썬 한 줄짜리 다른 라이너 일 수도 있습니다. 두 목록의 크기가 동일하거나 같지 않으면이 방법이 효과적입니다. 아무것도 가치가없는 한 가지는 a와 b를 수정할 것입니다. 문제가 있다면 다른 솔루션을 사용해야합니다.

    a = ['f', 'o', 'o']
    b = ['hello', 'world']
    sum([[a.pop(0), b.pop(0)] for i in range(min(len(a), len(b)))],[])+a+b
    ['f', 'hello', 'o', 'world', 'o']
    
  12. ==============================

    12.다음은리스트 라이브러리를 사용하는 라이너입니다. 다른 라이브러리는 없습니다.

    다음은리스트 라이브러리를 사용하는 라이너입니다. 다른 라이브러리는 없습니다.

    list3 = [sub[i] for i in range(len(list2)) for sub in [list1, list2]] + [list1[-1]]
    

    부작용에 의한 초기 목록의 변경을 허용하는 경우 다음과 같은 또 다른 방법이 있습니다.

    [list1.insert((i+1)*2-1, list2[i]) for i in range(len(list2))]
    
  13. ==============================

    13.최단 시간에 멈춤 :

    최단 시간에 멈춤 :

    def interlace(*iters, next = next) -> collections.Iterable:
        """
        interlace(i1, i2, ..., in) -> (
            i1-0, i2-0, ..., in-0,
            i1-1, i2-1, ..., in-1,
            .
            .
            .
            i1-n, i2-n, ..., in-n,
        )
        """
        return map(next, cycle([iter(x) for x in iters]))
    

    물론, 다음 / __ next__ 메소드를 해결하는 것이 더 빠를 수도 있습니다.

  14. ==============================

    14.이것은 불쾌하지만 목록의 크기와 상관없이 작동합니다.

    이것은 불쾌하지만 목록의 크기와 상관없이 작동합니다.

    list3 = [element for element in list(itertools.chain.from_iterable([val for val in itertools.izip_longest(list1, list2)])) if element != None]
    
  15. ==============================

    15.다른 질문에 대한 답변에서 영감을 얻은 여러 가지 한 가지 방법 :

    다른 질문에 대한 답변에서 영감을 얻은 여러 가지 한 가지 방법 :

    import itertools
    
    list(itertools.chain.from_iterable(itertools.izip_longest(list1, list2, fillvalue=object)))[:-1]
    
    [i for l in itertools.izip_longest(list1, list2, fillvalue=object) for i in l if i is not object]
    
    [item for sublist in map(None, list1, list2) for item in sublist][:-1]
    
  16. ==============================

    16.나는 간단 할거야 :

    나는 간단 할거야 :

    chain.from_iterable( izip( list1, list2 ) )
    

    추가 저장소 요구 사항을 만들지 않고도 반복기가 제공됩니다.

  17. ==============================

    17.목록 작성과 함께 하기엔 너무 늙습니다.

    목록 작성과 함께 하기엔 너무 늙습니다.

    import operator
    list3 = reduce(operator.add, zip(list1, list2))
    
  18. from https://stackoverflow.com/questions/3678869/pythonic-way-to-combine-two-lists-in-an-alternating-fashion by cc-by-sa and MIT license