How do I concatenate two lists in Python?

前端 未结 25 1921
时光取名叫无心
时光取名叫无心 2020-11-21 06:18

How do I concatenate two lists in Python?

Example:

listone = [1, 2, 3]
listtwo = [4, 5, 6]

Expected outcome:

>&g         


        
相关标签:
25条回答
  • 2020-11-21 06:40

    How do I concatenate two lists in Python?

    As of 3.9, these are the most popular stdlib methods for concatenating two (or more) lists in python.

    Footnotes

    1. This is a slick solution because of its succinctness. But sum performs concatenation in a pairwise fashion, which means this is a quadratic operation as memory has to be allocated for each step. DO NOT USE if your lists are large.

    2. See chain and chain.from_iterable from the docs. You will need to import itertools first. Concatenation is linear in memory, so this is the best in terms of performance and version compatibility. chain.from_iterable was introduced in 2.6.

    3. This method uses Additional Unpacking Generalizations (PEP 448), but cannot generalize to N lists unless you manually unpack each one yourself.

    4. a += b and a.extend(b) are more or less equivalent for all practical purposes. += when called on a list will internally call list.__iadd__, which extends the first list by the second.


    Performance

    2-List Concatenation1

    There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style.

    N-List Concatenation

    Plots have been generated using the perfplot module. Code, for your reference.

    1. The iadd (+=) and extend methods operate in-place, so a copy has to be generated each time before testing. To keep things fair, all methods have a pre-copy step for the left-hand list which can be ignored.


    Comments on Other Solutions

    • DO NOT USE THE DUNDER METHOD list.__add__ directly in any way, shape or form. In fact, stay clear of dunder methods, and use the operators and operator functions like they were designed for. Python has careful semantics baked into these which are more complicated than just calling the dunder directly. Here is an example. So, to summarise, a.__add__(b) => BAD; a + b => GOOD.

    • Some answers here offer reduce(operator.add, [a, b]) for pairwise concatenation -- this is the same as sum([a, b], []) only more wordy.

    • Any method that uses set will drop duplicates and lose ordering. Use with caution.

    • for i in b: a.append(i) is more wordy, and slower than a.extend(b), which is single function call and more idiomatic. append is slower because of the semantics with which memory is allocated and grown for lists. See here for a similar discussion.

    • heapq.merge will work, but its use case is for merging sorted lists in linear time. Using it in any other situation is an anti-pattern.

    • yielding list elements from a function is an acceptable method, but chain does this faster and better (it has a code path in C, so it is fast).

    • operator.add(a, b) is an acceptable functional equivalent to a + b. It's use cases are mainly for dynamic method dispatch. Otherwise, prefer a + b which is shorter and more readable, in my opinion. YMMV.

    0 讨论(0)
  • 2020-11-21 06:41

    For cases with a low number of lists you can simply add the lists together or use in-place unpacking (available in Python-3.5+):

    In [1]: listone = [1, 2, 3] 
       ...: listtwo = [4, 5, 6]                                                                                                                                                                                 
    
    In [2]: listone + listtwo                                                                                                                                                                                   
    Out[2]: [1, 2, 3, 4, 5, 6]
                                                                                                                                                                                         
    In [3]: [*listone, *listtwo]                                                                                                                                                                                
    Out[3]: [1, 2, 3, 4, 5, 6]
    

    As a more general way for cases with more number of lists, as a pythonic approach, you can use chain.from_iterable()1 function from itertoold module. Also, based on this answer this function is the best; or at least a very food way for flatting a nested list as well.

    >>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    >>> import itertools
    >>> list(itertools.chain.from_iterable(l))
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    1. Note that `chain.from_iterable()` is available in Python 2.6 and later. In other versions, use `chain(*l)`.
    0 讨论(0)
  • 2020-11-21 06:42

    As already pointed out by many, itertools.chain() is the way to go if one needs to apply exactly the same treatment to both lists. In my case, I had a label and a flag which were different from one list to the other, so I needed something slightly more complex. As it turns out, behind the scenes itertools.chain() simply does the following:

    for it in iterables:
        for element in it:
            yield element
    

    (see https://docs.python.org/2/library/itertools.html), so I took inspiration from here and wrote something along these lines:

    for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
        print header + ':'
        for path in iterable:
            [...]
            command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
            print >> SCRIPT , command, flag, srcPath, mergedDirPath
            [...]
    

    The main points to understand here are that lists are just a special case of iterable, which are objects like any other; and that for ... in loops in python can work with tuple variables, so it is simple to loop on multiple variables at the same time.

    0 讨论(0)
  • 2020-11-21 06:43

    If you can't use the plus operator (+), you can use the operator import:

    import operator
    
    listone = [1,2,3]
    listtwo = [4,5,6]
    
    result = operator.add(listone, listtwo)
    print(result)
    
    >>> [1, 2, 3, 4, 5, 6]
    

    Alternatively, you could also use the __add__ dunder function:

    listone = [1,2,3]
    listtwo = [4,5,6]
    
    result = list.__add__(listone, listtwo)
    print(result)
    
    >>> [1, 2, 3, 4, 5, 6]
    
    0 讨论(0)
  • 2020-11-21 06:43

    So there are two easy ways.

    1. Using +: It creates a new list from provided lists

    Example:

    In [1]: a = [1, 2, 3]
    
    In [2]: b = [4, 5, 6]
    
    In [3]: a + b
    Out[3]: [1, 2, 3, 4, 5, 6]
    
    In [4]: %timeit a + b
    10000000 loops, best of 3: 126 ns per loop
    
    1. Using extend: It appends new list to existing list. That means it does not create a separate list.

    Example:

    In [1]: a = [1, 2, 3]
    
    In [2]: b = [4, 5, 6]
    
    In [3]: %timeit a.extend(b)
    10000000 loops, best of 3: 91.1 ns per loop
    

    Thus we see that out of two of most popular methods, extend is efficient.

    0 讨论(0)
  • 2020-11-21 06:45

    This question directly asks about joining two lists. However it's pretty high in search even when you are looking for a way of joining many lists (including the case when you joining zero lists).

    I think the best option is to use list comprehensions:

    >>> a = [[1,2,3], [4,5,6], [7,8,9]]
    >>> [x for xs in a for x in xs]
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    You can create generators as well:

    >>> map(str, (x for xs in a for x in xs))
    ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    

    Old Answer

    Consider this more generic approach:

    a = [[1,2,3], [4,5,6], [7,8,9]]
    reduce(lambda c, x: c + x, a, [])
    

    Will output:

    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    Note, this also works correctly when a is [] or [[1,2,3]].

    However, this can be done more efficiently with itertools:

    a = [[1,2,3], [4,5,6], [7,8,9]]
    list(itertools.chain(*a))
    

    If you don't need a list, but just an iterable, omit list().

    Update

    Alternative suggested by Patrick Collins in the comments could also work for you:

    sum(a, [])
    
    0 讨论(0)
提交回复
热议问题