2012-04-30 36 views
6

Đối với hai danh sách,danh sách phù hợp trong python: có được chỉ số của một danh sách phụ trong một danh sách lớn hơn

a = [1, 2, 9, 3, 8, ...] (no duplicate values in a, but a is very big) 
b = [1, 9, 1,...]   (set(b) is a subset of set(a), 1<<len(b)<<len(a)) 

indices = get_indices_of_a(a, b) 

làm thế nào để chúng ta hãy trở lại get_indices_of_aindices = [0, 2, 0,...] với array(a)[indices] = b? Có phương pháp nhanh hơn sử dụng a.index, quá lâu không?

Đặt b một tập hợp là một phương pháp nhanh chóng kết hợp danh sách và chỉ mục quay lại (xem compare two lists in python and return indices of matched values), nhưng nó sẽ mất chỉ mục của số 1 thứ hai cũng như chuỗi chỉ số trong trường hợp này.

Trả lời

12

Một phương pháp nhanh (khi a là một danh sách lớn) sẽ được sử dụng một dict để lập bản đồ giá trị trong a để chỉ số:

>>> index_dict = dict((value, idx) for idx,value in enumerate(a)) 
>>> [index_dict[x] for x in b] 
[0, 2, 0] 

này sẽ mất thời gian tuyến tính trong trường hợp trung bình, so với sử dụng a.index mà sẽ mất thời gian bậc hai.

+0

+1. Đây là một câu trả lời hay cho các danh sách lớn, nơi nó sẽ giảm đáng kể thời gian cần thiết - một cách tự nhiên trên các danh sách nhỏ việc tạo ra dict sẽ mất nhiều thời gian hơn nó sẽ tiết kiệm được. Với nhận xét của người hỏi về câu trả lời của tôi, có vẻ như các danh sách lớn có liên quan, vì vậy đây là câu trả lời mong muốn. –

7

Giả sử chúng ta đang làm việc với danh sách nhỏ hơn, đây là dễ dàng như:

>>> a = [1, 2, 9, 3, 8] 
>>> b = [1, 9, 1] 
>>> [a.index(item) for item in b] 
[0, 2, 0] 

Mở danh sách lớn hơn, điều này sẽ trở nên khá tốn kém.

(Nếu có trùng lặp, lần xuất hiện đầu tiên sẽ luôn là lần xuất hiện trong danh sách kết quả, nếu not set(b) <= set(a), bạn sẽ nhận được một ValueError).

+0

Cảm ơn rất nhiều! Không có bản sao, nhưng một là rất lớn, và b là không nhỏ hoặc mặc dù len (b) << len (a). Sử dụng a.index (mục) đang thực hiện tìm kiếm trong một giá trị cho mỗi giá trị trong b ... có phương pháp nhanh hơn không? – user1342516

+0

@ user1342516 Yup, xem [câu trả lời của interjay] (http://stackoverflow.com/a/10385786/722121). –

+0

bạn có thể thêm điều này vào giải pháp của mình để xóa trường hợp ValueError: [a.index (mục) cho mặt hàng trong b nếu mục trong a] –

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