Câu hỏi Làm thế nào để nối hai danh sách bằng Python?


Làm thế nào để tôi nối hai danh sách bằng Python?

Thí dụ:

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

Kết quả dự kiến:

>>> joinedlist
[1, 2, 3, 4, 5, 6]

1643
2017-11-12 07:04


gốc


còn nếu listone là [3,2,1]? Liệu đầu ra có thay đổi không? - barkmadley
'hợp nhất' thành 'tạo một bản sao nông', 'sao chép sâu' hoặc 'lặp lại từ'? (@Clergyman, nó không hề quan trọng) - smci
Không phải hoạt động này được gọi là sự kết hợp thay vì hợp nhất? Tôi luôn nghĩ rằng việc sáp nhập có nghĩa là ghép nối + phân loại. - Lenar Hoyt
Bạn có muốn đơn giản không nối thêm, hoặc bạn có muốn hợp nhất hai danh sách theo thứ tự sắp xếp? Bạn mong đợi sản lượng gì cho [1,3,6] và [2,4,5]? Chúng ta có thể giả định cả hai danh sách con đã được sắp xếp (như trong ví dụ của bạn)? - smci
@LenarHoyt Đúng. Việc hợp nhất ngụ ý một số loại sắp xếp tùy ý hoặc quan hệ ở mức tối thiểu. - Benjamin R


Các câu trả lời:


Bạn có thể dùng + nhà điều hành để kết hợp chúng:

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

mergedlist = listone + listtwo

Đầu ra:

>>> mergedlist
[1,2,3,4,5,6]

2704
2017-11-12 07:07



hiện điều này tạo ra một bản sao sâu của listone và appends listtwo? - Daniel F
@Daniel nó sẽ tạo ra một danh sách mới với một bản sao nông của các mục trong danh sách đầu tiên, tiếp theo là một bản sao nông của các mục trong danh sách thứ hai. Sử dụng copy.deepcopy để lấy bản sao sâu của danh sách. - Daniel G
một chi tiết hữu ích khác ở đây: listone += listtwo kết quả trong listone == [1, 2, 3, 4, 5, 6] - rickcnagy
@ br1ckb0t sẽ thay đổi những gì mà listone đang trỏ tới? Vì thế:list3 = listone  listone+=listtwo       List3 có thay đổi không? - MikeH
nó thay đổi list3. Tuy nhiên, nếu đó không phải là một vấn đề, nó dễ đọc hơn để thêm hai danh sách thay vì tạo một danh sách mới. - rickcnagy


Nó cũng có thể tạo ra một máy phát điện mà chỉ đơn giản là lặp qua các mục trong cả hai danh sách. Điều này cho phép bạn chuỗi các danh sách (hoặc bất kỳ lặp lại) với nhau để xử lý mà không sao chép các mục vào một danh sách mới:

import itertools
for item in itertools.chain(listone, listtwo):
   # do something with each list item

215
2017-11-12 20:01



Đây là cách tốt hơn vì nó cũng làm việc với mảng numpy. - d.putto
điều này sẽ làm việc theo cùng một cách: mergedList = itertools.chain (listone, listtwo) cho mục trong mergedList: - zakdances
@ d.putto: truy cập mục riêng lẻ rất chậm đối với các mảng cố định (mỗi truy cập yêu cầu phải chuyển đổi bộ nhớ thô với kiểu C thành đối tượng Python. np.dot() làm việc trên các loại C trực tiếp mà không có chuyến đi vòng tới Python và do đó nhanh chóng). Bạn đã có thể sử dụng merged = np.r_[a, b] để có được mảng numpy nối. - jfs


Bạn có thể sử dụng các bộ để có được danh sách các giá trị duy nhất được hợp nhất

mergedlist = list(set(listone + listtwo))

151
2017-09-20 08:43



điều này sẽ mất thông tin đặt hàng. - aaronasterling
Đúng, tuy nhiên, nó cũng sẽ loại bỏ các bản sao, nếu đó là những gì bạn quan tâm. Thêm danh sách cùng sẽ không làm điều đó. - metasoarous
Tốt hơn listone + [x for x in listtwo if x not in listone] - Natim
Nếu tôi có danh sách các danh sách, chẳng hạn như danh sách này: [[0, 5], [1, 10], [0, 7], [3, 5]]  Làm thế nào bạn sẽ hợp nhất chúng để tránh trùng lặp trong khóa (giá trị đầu tiên trong mỗi danh sách phụ), nhưng nếu chúng là bản sao, kết thúc bằng tổng của các giá trị thứ hai? Giống như vậy: [[0, 12], [1, 10], [3, 5]]  Cảm ơn - Jose Salvatierra
+1 IMHO đây là cách chính xác để "hợp nhất" (công đoàn) danh sách trong khi câu trả lời "được chấp thuận" mô tả cách kết hợp / thêm danh sách (multiset) - alfasin


Bạn cũng có thể sử dụng extend để thêm list thêm kết thúc của một số khác:

listone = [1,2,3]
listtwo = [4,5,6]
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)

100
2018-02-25 15:13



Bạn chỉ có thể sử dụng listone.extend (listtwo) nhưng nó sẽ không được dùng nữa - Sergey Ivanov
@SergeyIvanov không có nó sẽ không. list.extend không đi đâu cả. - Jim Fasarakis Hilliard


Python >= 3.5 thay thế: [*l1, *l2]

Mặc dù đây là câu trả lời cũ, một giải pháp thay thế khác đã được giới thiệu thông qua việc chấp nhận PEP 448 đáng được nhắc tới.

PEP, có tiêu đề Bổ sung Unpacking Generalizations, thường giảm một số hạn chế cú pháp khi sử dụng dấu sao * biểu thức bằng Python; với nó, tham gia hai danh sách (áp dụng cho bất kỳ iterable) có thể bây giờ cũng được thực hiện với:

>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]

#unpack both iterables in a list literal
>>> joinedList = [*l1, *l2]
>>> print(joinedList)
[1, 2, 3, 4, 5, 6]

Chức năng này được định nghĩa cho Python 3.5 nó chưa được quay lại các phiên bản trước trong 3.x gia đình. Trong các phiên bản không được hỗ trợ SyntaxError sẽ được nâng lên.

Như với các cách tiếp cận khác, điều này cũng vậy tạo thành bản sao nông của các phần tử trong danh sách tương ứng.


Các lộn ngược với cách tiếp cận này là bạn thực sự không cần danh sách để thực hiện nó, bất kỳ thứ gì có thể lặp lại sẽ làm được. Như đã nêu trong PEP:

Điều này cũng hữu ích như một cách dễ đọc hơn để tổng hợp các biến lặp thành một   danh sách, chẳng hạn như my_list + list(my_tuple) + list(my_range) bây giờ là   tương đương với chỉ [*my_list, *my_tuple, *my_range].

Vì vậy, trong khi bổ sung với + sẽ nâng cao TypeError do loại không phù hợp:

l = [1, 2, 3]
r = range(4, 7)
res = l + r

Sau đây sẽ không:

res = [*l, *r]

bởi vì trước tiên nó sẽ giải nén nội dung của các iterables và sau đó chỉ cần tạo một list từ nội dung.


97
2017-11-12 07:07



điều này:lst = [1,2,3,*[4,5,6]] nói Expected:] - Mahesha999
@ Mahesha999 dường như không thể xác minh điều đó, nó hoạt động như mong đợi đối với tôi. - Jim Fasarakis Hilliard


Điều này khá đơn giản, tôi nghĩ nó thậm chí còn được thể hiện trong hướng dẫn:

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

57
2018-03-05 09:15



Và điều này cũng hoạt động khi listone và listtwo có số lượng phần tử khác nhau ;-) - albus_c


Bạn chỉ có thể sử dụng + hoặc là += toán tử như sau:

a = [1, 2, 3]
b = [4, 5, 6]

c = a + b

Hoặc là:

c = []
a = [1, 2, 3]
b = [4, 5, 6]

c += (a + b)

Ngoài ra, nếu bạn muốn các giá trị trong danh sách được hợp nhất là duy nhất, bạn có thể thực hiện:

c = list(set(a + b))

33
2017-10-09 23:21





Câu hỏi này yêu cầu trực tiếp về việc tham gia hai danh sách. Tuy nhiên nó khá cao trong tìm kiếm ngay cả khi bạn đang tìm kiếm một cách để tham gia nhiều danh sách (bao gồm cả trường hợp khi bạn tham gia danh sách số không). Xem xét cách tiếp cận chung chung hơn này:

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

Sản lượng sẽ:

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

Lưu ý, điều này cũng hoạt động chính xác khi a Là [] hoặc là [[1,2,3]].

Tuy nhiên, điều này có thể được thực hiện hiệu quả hơn với itertools:

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

Nếu bạn không cần list, nhưng chỉ là một lần lặp lại, bỏ qua list().

Cập nhật

Thay thế được đề xuất bởi Patrick Collins trong các ý kiến ​​cũng có thể làm việc cho bạn:

sum(a, [])

29
2018-02-05 05:01



sum(a,[]) chỉ hoạt động khi "a" là danh sách các danh sách. - Procyclinsur
Chú thích Python 3: reduce hiện đang ở functools vì vậy bạn sẽ cần phải nhập nó trước. - Jim Fasarakis Hilliard


Cần lưu ý rằng itertools.chain hàm chấp nhận số lượng đối số biến:

>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']
>>> [i for i in itertools.chain(l1, l2)]
['a', 'b', 'c']
>>> [i for i in itertools.chain(l1, l2, l3)]
['a', 'b', 'c', 'd', 'e', 'f']

Nếu một bộ lặp (tuple, list, generator, vv) là đầu vào, from_iterable phương thức lớp có thể được sử dụng:

>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']

20
2017-07-21 00:53





Với Python 3.3+ bạn có thể sử dụng năng suất từ:

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

def merge(l1, l2):
    yield from l1
    yield from l2

>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]

Hoặc, nếu bạn muốn hỗ trợ một số các trình vòng lặp tùy ý:

def merge(*iters):
    for it in iters:
        yield from it

>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]

19
2017-07-07 13:30