2010-03-05 34 views
15

Tôi có hai danh sách được bảo đảm có cùng độ dài. Tôi muốn so sánh các giá trị tương ứng trong danh sách (ngoại trừ mục đầu tiên) và in ra các giá trị không khớp. Cách tôi đang thực hiện nó giống như thế nàyCách Pythonic để so sánh hai danh sách và in ra sự khác biệt

i = len(list1) 
if i == 1: 
    print 'Nothing to compare' 
else: 
    for i in range(i): 
     if not (i == 0): 
      if list1[i] != list2[i]: 
       print list1[i] 
       print list2[i] 

Có cách nào tốt hơn để làm điều này không? (Python 2.x)

+2

chức năng lập trình với cứu hộ: nhìn vào bản đồ và zip! – mjv

Trả lời

20
list1=[1,2,3,4] 
list2=[1,5,3,4] 
print [(i,j) for i,j in zip(list1,list2) if i!=j] 

Output:

[(2, 5)] 

Edit: Dễ dàng mở rộng để bỏ qua n mục đầu tiên (cùng công suất):

list1=[1,2,3,4] 
list2=[2,5,3,4] 
print [(i,j) for i,j in zip(list1,list2)[1:] if i!=j] 
+0

giải nén tuple sẽ nhanh hơn lập chỉ mục. cũng cắt sẽ không hoạt động trong py3k – SilentGhost

+0

xoá chỉ mục, tốt hơn? :) – Mizipzor

+1

Chính xác những gì tôi đang tìm kiếm. Cảm ơn – randomThought

2

chỉnh sửa: oops, không thấy "bỏ qua mục đầu tiên" phần

from itertools import islice,izip 

for a,b in islice(izip(list1,list2),1,None): 
    if a != b: 
     print a, b 
2

Có một lớp đẹp gọi difflib.SequenceMatcher trong thư viện chuẩn cho điều đó.

+0

Tôi nhận được cách bạn sẽ sử dụng điều này để tìm các khối phù hợp, nhưng không phải là các mục khác nhau. Hay tôi đang thiếu một cái gì đó? – RyanWilcox

+0

@RyanWilcox: điều đó phải dễ dàng trong O (n) khi bạn có các khối phù hợp –

2

Ghi nhận các yêu cầu để bỏ qua dòng đầu tiên:

from itertools import izip 
both = izip(list1,list2) 
both.next() #skip the first 
for p in (p for p in both if p[0]!=p[1]): 
    print pair 
  1. Điều này sử dụng izip, phiên bản lặp (itertools) của zip, để tạo trình lặp qua cặp giá trị. Bằng cách này bạn không sử dụng hết dung lượng bộ nhớ tạo ra một danh sách nén hoàn chỉnh.
  2. Nó bước một lần lượt both để tránh xử lý mục đầu tiên và tránh phải thực hiện so sánh chỉ mục trên mỗi bước qua vòng lặp. Nó cũng làm cho nó sạch hơn để đọc.
  3. Cuối cùng nó bước qua mỗi bộ trở về từ một máy phát điện chỉ mang lại các cặp không bằng nhau. lọc
5

Không ai đề cập:

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

aToCompare = a[1:] 
bToCompare = b[1:] 

c = filter(lambda x: (not(x in aToCompare)), bToCompare) 
print c 
2

Bạn có thể sử dụng bộ:

>>> list1=[1,2,3,4] 
>>> list2=[1,5,3,4] 
>>> set(list1[1:]).symmetric_difference(list2[1:]) 
set([2, 5]) 
+0

Tôi không nghĩ rằng điều này khá phù hợp. Họ muốn so sánh phần tử đầu tiên của một danh sách với phần tử đầu tiên của phần tử kia và từ thứ hai đến thứ hai, v.v.Vì các bộ không được đặt hàng, tôi không nghĩ điều này phù hợp với vấn đề này. – MatrixFrog

+0

Tuy nhiên, bộ là một cách thú vị để đối phó với loại sự cố này ... – RyanWilcox

0

Giả sử hai loại đều bình đẳng và có cùng chiều dài:

list1=[1,2,3,4] 
list2=[1,5,3,4] 
print list1==list2 
Các vấn đề liên quan