2016-06-03 22 views
7

Tôi đang cố gắng thiết lập dữ liệu để chuyển đổi thành mảng có nhiều mảng. Tôi có ba danh sách. Hai là một chiều, và một là hai chiều.Hợp nhất danh sách 1D và 2D trong python

a = [1,2,3] 
b = [4,5,6] 
c = [ [7,8],[9,10],[11,12] ] 

Tôi muốn kết thúc với điều này:

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

Tôi đã cố gắng sử dụng zip(), nhưng nó không đi sâu vào mảng 2D.

Trả lời

4

Giả sử bạn không ngại nếu sử dụng NumPy trong chính chuyển đổi, những điều sau đây sẽ hoạt động.

from numpy import array 

a = array([1, 2, 3]) 
b = array([4, 5, 6]) 
c = array([[7, 8], [9, 10], [11, 12]]) 

result = array(list(zip(a, b, c[:, 0], c[:, 1]))) 

Lưu ý rằng c[:, n] sẽ chỉ hoạt động với các mảng NumPy, không phải danh sách Python chuẩn.

+1

Điều này làm việc tốt cho trường hợp đơn giản, nhưng không mở rộng hoặc thích ứng tốt với các thay đổi. Nếu mảng c chứa một số lượng lớn các cột, điều đó có nghĩa là phải giải quyết riêng từng cột: 'c [:, 0], c [:, 1], c [:, 2], c [:, 3], .. .' – Rachie

1

Trong trường hợp bạn muốn để hoạt động với danh sách Python tiêu chuẩn mà bạn có thể sử dụng zip và sau đó xử lý mỗi hàng sau:

from itertools import chain 

a = [1,2,3] 
b = [4,5,6] 
c = [[7,8], [9,10], [11,12]] 

[list(chain.from_iterable(y if isinstance(y, list) else [y] for y in x)) for x in zip(a, b, c)] 
3

Một giải pháp numpy (theo tag của bạn) sẽ là

In [398]: np.vstack([a,b,np.array(c).T]).T 
Out[398]: 
array([[ 1, 4, 7, 8], 
     [ 2, 5, 9, 10], 
     [ 3, 6, 11, 12]]) 

điều này làm cho c thành một mảng 2x3:

In [399]: np.array(c).T 
Out[399]: 
array([[ 7, 9, 11], 
     [ 8, 10, 12]]) 

mà sau đó có thể được xếp chồng lên nhau (được nối) theo chiều dọc với ab cũng có 3 thành phần.

zip(*c) là một hình thức danh sách các transpose

In [412]: list(zip(a,b,c)) 
Out[412]: [(1, 4, [7, 8]), (2, 5, [9, 10]), (3, 6, [11, 12])] 

In [418]: list(zip(a,b,*zip(*c))) 
Out[418]: [(1, 4, 7, 8), (2, 5, 9, 10), (3, 6, 11, 12)] 
3

Với python3 nó đơn giản như

a = [1,2,3] 
b = [4,5,6] 
c = [ [7,8],[9,10],[11,12] ] 
[[x, y, *z] for x, y, z in zip(a, b, c)] 
[[1, 4, 7, 8], [2, 5, 9, 10], [3, 6, 11, 12]] 
+0

xấu của tôi, tôi đã không nhận ra trình thông dịch python của tôi thực sự là 3.5 – njzk2

+1

Các phiên bản cũ hơn của Python 3 sẽ bị nghẹt thở trên '* z'. 3,0 qua 3.4 nâng cao 'Cú pháp Cú pháp: có thể sử dụng biểu thức được gắn dấu sao chỉ làm mục tiêu gán'. –

1

Đối với người mới bắt đầu, zip mang lại tuples, không danh sách, vì vậy bạn sẽ phải chuyển đổi sản lượng của nó vào danh sách:

def lzip(*args): 
    'Transforms the tuples yielded by zip into equivalent lists.' 
    for tup in zip(*args): 
     yield list(tup) 
    return 

# Later... 
a = [1, 2, 3] 
b = [4, 5, 6] 
c = [ 
    [7, 8], 
    [9, 10], 
    [11, 12], 
    ] 
lzip(a, b) 
# A generator that yields: [1, 4], [2, 5], [3, 6] 

Se cond, zip sẽ không trả về những gì bạn muốn bất kể điều gì, bởi vì thao tác bạn đang cố gắng thực hiện trên danh sách phụ của cghép nối, không nén.

Đầu tiên, lzip danh sách 1-d như trong ví dụ ở trên, sau đó ghép từng danh sách phụ kết quả với danh sách con phù hợp trong c.

Dưới đây, tôi đã sử dụng một danh sách hiểu để xây dựng danh sách kết hợp gán nó vào một biến, với hai biến cục bộ mới để làm cho hoạt động zip rõ ràng hơn:

heads = lzip(a, b) 
tails = c 
zipped = [head + tail for head, tail in zip(heads, tails)] 
# [[1, 4, 7, 8], [2, 5, 9, 10], [3, 6, 11, 12]] 

Các zip sản lượng 2-tuples chứa n & # x2060; đầu thứ và n & # x2060; đuôi thứ:

# First iteration: 
([1, 4], [7, 8]) 
# Next iteration: 
([2, 5], [9, 10]) 
# Last iteration: 
([3, 6], [11, 12]) 

những tuples được giải nén vào hai va riables bởi việc phân công (vô hình) head, tail = ... bên trong danh sách hiểu. Bản thân các tuple được vứt bỏ.

Kết hợp danh sách ("thêm") với head + tail kết hợp hai danh sách thành một. Trong trường hợp này, các cặp danh sách 2 phần tử trở thành các danh sách 4 phần tử riêng lẻ.

Cuối cùng, [] của danh sách hiểu được thu thập danh sách 4 phần tử thành một danh sách ... trong danh sách 4 phần tử.

Các vấn đề liên quan