2012-10-25 34 views
6

Đây là câu hỏi cơ bản về thao tác danh sách trong Mathematica. Tôi có một danh sách lớn trong đó mỗi phần tử có dạng sơ đồ sau: {List1, List2, Number}. Ví dụ:Trích xuất nhanh các phần tử từ danh sách lồng nhau

a = {{{1,2,3},{1,3,2},5},{{1,4,5},{1,0,2},10},{{4,5,3},{8,3,4},15}}}.

Tôi muốn tạo một danh sách mới chỉ có một số phần từ mỗi danh sách phụ. Ví dụ: chọn phần tử thứ ba từ mỗi danh sách con để cung cấp {5,10,15} từ phần trên. Hoặc thả phần tử thứ ba để trả về {{{1,2,3}, {1,3,2}}, {{1,4,5}, {1,0,2}}, {{4,5, 3}, {8,3,4}}}.

tôi có thể làm điều này bằng cách sử dụng lệnh bảng để xây dựng danh sách mới, ví dụ,

Table[a[[i]][[3]],{i,1,Length[a]} 

nhưng tôi đã tự hỏi nếu có một phải nhanh hơn cách mà sẽ làm việc trên các danh sách lớn.

Trả lời

7

Trong Mathematica phiên bản 5 trở lên, bạn có thể sử dụng từ khóa Tất cả trong nhiều cách để xác định một danh sách traversal

Ví dụ, thay vì Bảng của bạn, bạn có thể viết

a[[All,3]] 

Tại đây Mathematica chuyển đổi Tất cả thành tất cả các chỉ số có thể chấp nhận cho dimen đầu tiên sion sau đó lấy cái thứ ba của kích thước tiếp theo.

Thường thì hiệu quả hơn để thực hiện việc này hơn là tạo vòng lặp với ngôn ngữ lập trình Mathematica. Nó thực sự tốt cho đồng nhất danh sách nơi những thứ bạn muốn chọn hoặc quét qua luôn luôn tồn tại.

Ký hiệu và lối tắt hiệu quả khác là ;; cú pháp:

a[[ All, 1 ;; 2]] 

sẽ quét cấp đầu tiên và lấy mọi thứ từ phần 1 đến phần 2 của mỗi danh sách con, giống hệt như trường hợp thứ hai của bạn.

Thực tế Tất cả và ;; có thể được kết hợp với bất kỳ số lượng các cấp. ;; thậm chí có thể được sử dụng theo cách tương tự như bất kỳ iterator trong Mathematica:

a[[ start;;end;;step ]] 

sẽ làm những điều tương tự như

Table[ a[[i]], {i,start,end,step}] 

và bạn có thể bỏ qua một trong những khởi đầu, kết thúc hoặc bước, nó được làm đầy với mặc định là 1, Độ dài [(của danh sách ngầm)] và 1.

Một điều bạn có thể muốn tra cứu trong Trợ giúp của Mathematica là ReplacePartMapAt cho phép thay thế các biểu thức có cấu trúc theo chương trình. Điều quan trọng để sử dụng hiệu quả này là trong ReplacePart bạn có thể sử dụng patterns để xác định tọa độ của những thứ cần thay thế và bạn có thể xác định các hàm để áp dụng cho chúng.

Ví dụ với dữ liệu của bạn

ReplacePart[a, {_, 3} -> 0] 

sẽ thay thế tất cả các phần thứ 3 của mỗi sublist với 0.

ReplacePart[a, {i : _, 3} :> 2*a[[i, 3]]] 

sẽ tăng gấp đôi mỗi phần thứ 3 của mỗi sublist.

+0

Cảm ơn; đây là những gì tôi đang tìm kiếm. – bartimaeus

+1

Lưu ý rằng nếu có thêm câu hỏi, bạn cũng có thể hỏi tại http://mathematica.stackexchange.com – ogerard

1

Bạn có thể sử dụng Part (viết tắt [[...]]) cho việc này:.

a[[All, 3]] 

a[[All, {1, 2}]] 
2

Như các tác giả đề nghị, phương pháp tiếp cận dựa trên phần cần dữ liệu cũng như hình thành, nhưng trường hợp được xây dựng để tách mạnh mẽ của Lists:

Sử dụng một mình,

a = {{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2}, 
10}, {{4, 5, 3}, {8, 3, 4}, 15}}; 

Cases[a,{_List,_List,n_}:>n,Infinity] 

{5, 10, 15} 

Các phần khác của một bản ghi có thể được trích xuất bằng các hình thức tương tự.

cách tiếp cận Part-based sẽ bịt miệng trên dữ liệu vô hình thành như:

badA = {{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2}, 
10}, {{4, 5, 3}, {8, 3, 4}, 15}, {baddata}, {{1, 2, 3}, 4}}; 

badA[[All,3]] 

{{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2}, 
10}, {{4, 5, 3}, {8, 3, 4}, 15}, {baddata}, {{1, 2, 3}, 
4}}[[All, 3]] 

, nhưng trường hợp sẽ bỏ qua rác, chỉ hoạt động trên phù hợp với dữ liệu

Cases[badA, {_List, _List, s_} :> s, Infinity] 

{5, 10, 15} 

hth,

Fred Klingener

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