2015-02-27 20 views
6

Giả sử tôi có hai danh sách (hoặc numpy.array s):Làm thế nào để so sánh hai danh sách trong python

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

Làm thế nào tôi có thể kiểm tra nếu mỗi phần tử của a là nhỏ hơn so với yếu tố b tương ứng tại các chỉ số giống nhau không? (Chỉ số Tôi giả đang bắt đầu từ 0) ví dụ:

at index 0 value of a = 1 < value of b = 4 
at index 1 value of a = 2 < value of b = 5 
at index 2 value of a = 3 < value of b = 6 

Nếu a là bằng [1,2,7], thì đó sẽ là không chính xác bởi vì ít giá trị chỉ số 2 của a là lớn hơn so với b. Ngoài ra, nếu chiều dài của a nhỏ hơn b, thì chỉ nên so sánh chỉ số của a với chỉ số của b.

Ví dụ cặp này a, b

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

ở chỉ số 0 và 1, giá trị của a nhỏ hơn b, do đó điều này cũng sẽ vượt qua kiểm tra.

P.S .--> Tôi phải sử dụng các điều kiện ở trên bên trong tuyên bố if. Và cũng vậy, không có yếu tố nào của a phải bằng với b tức là thấp hơn. Vui lòng sử dụng nhiều như công cụ tùy thích. (Mặc dù tôi đang sử dụng danh sách ở đây, bạn có thể chuyển đổi các danh sách trên vào mảng NumPy quá.)

Trả lời

4

Là một biến thể, nhanh chóng và ngắn

from operator import lt 
from itertools import starmap, izip 
all(starmap(lt, izip(a, b))) 
+0

@Antti Haapala, cho a và b, trong đó a = list (range (10000)) và b = list (range (1, 10001)) Trên hệ thống của tôi, giải pháp của bạn cho 809 micro giây và của tôi là 558 – Retard

+0

Thực sự của bạn là nhanh hơn: D vì ít tạo tuple. –

+0

Tôi rất tò mò về quy trình thử nghiệm của bạn. Có thể cung cấp mã cho bạn thử nghiệm không? (Bạn có thể sử dụng http://pythonfiddle.com/) – Exelian

12

trả lời cả hai phần với zipall

all(i < j for (i, j) in zip(a, b)) 

zip sẽ ghép các giá trị từ đầu a với các giá trị từ đầu b; lặp lại kết thúc khi có thể lặp lại ngắn hơn. all trả về True nếu và chỉ khi tất cả các mục trong một đã cho là đúng trong ngữ cảnh boolean. Ngoài ra, khi bất kỳ mục nào bị lỗi, False sẽ sớm được trả lại.

Ví dụ kết quả:

>>> a = [1,2,3] 
>>> b = [4,5,6] 
>>> all(i < j for (i, j) in zip(a, b)) 
True 
>>> a = [1,2,7] 
>>> b = [4,5,6] 
>>> all(i < j for (i, j) in zip(a, b)) 
False 
>>> a = [1,2] 
>>> b = [4,5,-10] 
>>> all(i < j for (i, j) in zip(a, b)) 
True 

Thời gian với IPython 3.4.2:

In [1]: a = [1] * 10000 
In [2]: b = [1] * 10000 
In [3]: %timeit all(i < j for (i, j) in zip(a, b)) 
1000 loops, best of 3: 995 µs per loop 
In [4]: %timeit all(starmap(lt, zip(a, b))) 
1000 loops, best of 3: 487 µs per loop 

Vì vậy, các starmap là nhanh hơn trong trường hợp này. Nói chung 2 điều tương đối chậm trong Python: gọi hàm và tra cứu tên. Các starmap của Retard's solution dường như giành chiến thắng ở đây chính xác vì tuple mang lại từ zip có thể được cấp dưới dạng * args với hàm dựng sẵn lt, trong khi mã của tôi cần phải giải mã nó.

2

Kể từ khi câu hỏi này có một thẻ numpy, tôi figured tôi sẽ cung cấp một giải pháp numpy.

Bạn chỉ có thể sử dụng toán tử < trên arrays có chiều dài bằng nhau, do đó nếu arrays có độ dài khác nhau, bạn cần phải rút ngắn thời lượng dài nhất.

In [26]: import numpy as np 

In [27]: a = [1,2,3] 

In [28]: b = [4,5,6] 

In [29]: np.all(a < b) 
Out[29]: True 

In [30]: a = [1,2] 

In [31]: b = [3,4,5] 

In [32]: shortest = min(len(a), len(b)) 

In [33]: np.all(a[:shortest] < b[:shortest]) 
Out[33]: True 
1

Chỉ cần một cách khác, và không chắc chắn làm thế nào nó thực hiện chống lại các câu trả lời khác:

a = [1,2,3] 
b = [4,5,6] 
if filter(lambda x: x[0] < x[1], zip(a,b)): 
    return True 

Tôi đang sử dụng nó trong if-tuyên bố kể từ khi câu hỏi cho thấy, rằng nó sẽ là được sử dụng như thế, và không cần thiết phải chuyển đổi bool ở đó. Nếu không, tôi đã bọc bộ lọc() bên trong bool(). Một lần nữa, đây chỉ là để chứng minh một cách tiếp cận thay thế, không có nghĩa là phương pháp hiệu quả nhất.

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