2016-11-01 31 views
8

Đây là những bước logic mà tôi cần phải thực hiện trong danh sách của tôi về danh sáchsắp xếp danh sách liệt kê và nhận được chỉ số trong danh sách được phân loại

a = [[5,2],[7,4],[0,3]] 
  1. sắp xếp danh sách của danh sách theo cách như vậy mà đầu ra trông giống như

    7,5,4,3,2,0 
    
  2. lấy tọa độ của các yếu tố được sắp xếp trong danh sách ban đầu, mà trong trường hợp này nên sản xuất như sản lượng

    (1,0) 
    (0,0) 
    (1,1) 
    (2,1) 
    (0,1) 
    (2,0) 
    

tôi đã cố gắng sử dụng các sort, sortedargwhere theo những cách khác nhau nhưng tôi không nhận được kết quả hợp lý, tôi đoán trước hết vì sortsorted có thể sắp xếp một danh sách sau đây chỉ có một trục tại một thời điểm

+0

Bạn chỉ muốn đầu ra các chỉ số, hay bạn cũng muốn đầu ra các giá trị (ví dụ 7, 5,4,3,2,0)? –

+0

@ PM2Ring Tôi không cần phải xuất các giá trị, nhưng tôi cần để có thể nhận được chúng để tính toán thêm – johnhenry

+1

những gì về bản sao? – Jodrell

Trả lời

8

Mã này sẽ làm việc cho một danh sách liệt kê. Danh sách nội bộ không cần phải có cùng độ dài.

Ở mỗi cấp, chúng tôi lặp qua danh sách bằng cách sử dụng enumerate để lấy mục danh sách và chỉ mục của nó. Ở cấp cao nhất, mỗi mục là một danh sách khác và vòng lặp bên trong lặp lại trên mỗi danh sách đó để lấy chỉ mục và giá trị của chúng, lưu trữ các chỉ mục (như một bộ tuple) trong một bộ dữ liệu cũng chứa giá trị đó. Sau đó, chúng tôi sắp xếp danh sách kết quả của các bộ dữ liệu (b) trên các giá trị, sau đó chia nó bằng cách sử dụng zip thành một bộ gồm tất cả các chỉ mục và một bộ giá trị.

from operator import itemgetter 

a = [[5, 2], [7, 4], [0, 3]] 

b = [((i, j), v) for i, t in enumerate(a) for j, v in enumerate(t)] 
b.sort(key=itemgetter(-1), reverse=True) 
print(b) 
coords, vals = zip(*b) 
print(vals) 
print(coords) 

đầu ra

[((1, 0), 7), ((0, 0), 5), ((1, 1), 4), ((2, 1), 3), ((0, 1), 2), ((2, 0), 0)] 
(7, 5, 4, 3, 2, 0) 
((1, 0), (0, 0), (1, 1), (2, 1), (0, 1), (2, 0)) 
+2

Aka [biến đổi Schwartz] (https://en.wikipedia.org/wiki/Schwartzian_transform) – Bergi

+0

@Bergi Cũng được phát hiện. :) Nó hiếm khi cần thiết để sử dụng nó một cách rõ ràng trong Python (mặc dù tôi đoán sử dụng một chức năng quan trọng với sắp xếp/sắp xếp có hiệu quả là một loại Schwartz dưới mui xe), do đó, nó là kinda vui vẻ để có một cái cớ tốt để sử dụng nó ở đây. –

8

Tạo từ điển có các khóa làm toạ độ thực tế và các giá trị như các số đó, như thế này

>>> a = [[5, 2], [7, 4], [0, 3]] 
>>> positions = { 
...  (idx1, idx2): col 
...  for idx1, row in enumerate(a) 
...  for idx2, col in enumerate(row) 
... } 
>>> positions 
{(0, 1): 2, (2, 0): 0, (0, 0): 5, (1, 0): 7, (1, 1): 4, (2, 1): 3} 

Bây giờ, sắp xếp các phím (tọa độ) của positions dựa trên các giá trị của chúng, như thế này

>>> sorted(positions, key=positions.get, reverse=True) 
[(1, 0), (0, 0), (1, 1), (2, 1), (0, 1), (2, 0)] 
1

Bạn có thể làm phẳng danh sách rồi sử dụng nó để sắp xếp và tìm chỉ mục.

a = [[5,2],[7,4],[0,3]] 
c = reduce(lambda x, y: x+y, a) 
b = sorted(c, reverse=True) 
for i in b: 
    print c.index(i)/2, c.index(i)%2 

Output:

1 0 
0 0 
1 1 
2 1 
0 1 
2 0 
+1

Điều này sẽ không hoạt động tốt nếu có bất kỳ giá trị lặp lại nào. Ngoài ra, nó giả định rằng các danh sách bên trong sẽ luôn có chính xác 2 mục. –

+0

@ PM2Ring trừ khi OP làm rõ tôi đoán danh sách bên trong với chính xác 2 mục là giả định hợp lý. – vks

+1

Đủ công bằng. Nhưng điểm về giá trị lặp lại vẫn đứng vững. ;) –

2

Bạn có thể sử dụng một loạt các comprehensions danh sách và zip khối, mặc dù khả năng đọc bị:

n, idxs = zip(*sorted(zip([i for sl in a for i in sl], [(col, row) for col in range(len(a)) for row in range(len(a[col]))]), key=lambda x: x[0], reverse=True)) 

print n, idxs 
>>> (7, 5, 4, 3, 2, 0) ((1, 0), (0, 0), (1, 1), (2, 1), (0, 1), (2, 0)) 

Nếu bạn cần một dict, chỉ cần thay thế zip(*..) lớp với dict()

2

Sử dụng Numpy, mà là khá nhanh hơn nhiều hơn so với mã python thường xuyên khi bạn đang đối phó với mảng lớn:

In [21]: a = np.array([[5,2],[7,4],[0,3]]) 
In [22]: x, y = np.unravel_index((-a).argsort(axis=None), a.shape) 

In [23]: indices = np.column_stack((x, y)) 

In [24]: indices 
Out[24]: 
array([[1, 0], 
     [0, 0], 
     [1, 1], 
     [2, 1], 
     [0, 1], 
     [2, 0]]) 

In [25]: a[x, y] 
Out[25]: array([7, 5, 4, 3, 2, 0]) 
+0

và tất cả những cách khác, cách tốt nhất để sử dụng là gì, nếu sau đó tôi cần sử dụng hai chỉ mục đầu tiên [1,0], [0,0] (ví dụ). Ý tôi là: hãy cân nhắc rằng tôi cần trích xuất [1] [0] và [0,0], tôi có thể làm gì? – johnhenry

+0

@johnhenry Kiểm tra cập nhật. Đó là một cách tổng quát hơn cung cấp cho bạn mảng được sắp xếp với một chỉ mục đơn giản. – Kasramvd

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