2010-10-04 28 views
36

tôi đang chơi với trăn và tôi có thể nhận được các giao điểm của hai danh sách:Python -Intersection của nhiều danh sách?

result = set(a).intersection(b) 

Bây giờ nếu d là một danh sách có chứa ab và một yếu tố thứ ba c, là có một built-in chức năng cho việc tìm kiếm giao điểm của cả ba danh sách bên trong d? Vì vậy, ví dụ,

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]] 

thì kết quả sẽ

[3,4] 

Trả lời

33

cho 2.4, bạn chỉ có thể xác định một chức năng giao lộ.

def intersect(*d): 
    sets = iter(map(set, d)) 
    result = sets.next() 
    for s in sets: 
     result = result.intersection(s) 
    return result 

cho các phiên bản mới hơn của python:

phương pháp ngã mất một số tiền tùy ý của các đối số

result = set(d[0]).intersection(*d[:1]) 

cách khác, bạn có thể cắt tập đầu tiên với bản thân để tránh slicing danh sách và tạo bản sao:

result = set(d[0]).intersection(*d) 

Tôi không thực sự chắc chắn đó sẽ là hiệu quả hơn và có cảm giác rằng nó sẽ phụ thuộc vào kích thước của d[0] và kích thước của danh sách trừ trăn có một kiểm tra sẵn có cho nó như

if s1 is s2: 
    return s1 

trong phương pháp giao nhau.

>>> d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]] 
>>> set(d[0]).intersection(*d) 
set([3, 4]) 
>>> set(d[0]).intersection(*d[1:]) 
set([3, 4]) 
>>> 
+0

@AaronMcSmooth: Nó cho đối tượng 'AttributeError: 'list' không có thuộc tính 'intersection'' nếu tôi làm điều đó. Tui bỏ lỡ điều gì vậy? – Legend

+0

@Legend. bạn phải ánh xạ nó tới một tập đầu tiên. Tôi bằng cách nào đó đã bỏ lỡ một thực tế rằng họ đã được danh sách.Sau đó, bạn chỉ có thể truyền danh sách (hoặc bất kỳ phương thức nào khác) vào phương thức 'intersection' – aaronasterling

+0

@AaronMcSmooth: Thực ra, không chắc tại sao nhưng tôi nhận được lỗi này bất kể tôi thử giải pháp nào:' TypeError: intersection() mất chính xác một đối số (3 đã cho) ' – Legend

40
set.intersection(*map(set,d)) 
+0

Bạn không chắc chắn có gì sai ở đây. Bây giờ nó mang lại cho tôi: 'TypeError: intersection() lấy chính xác một đối số (2 đã cho)' – Legend

+0

@Legend, bạn đang dùng phiên bản python nào? nó làm việc cho tôi. – aaronasterling

+0

@AaronMcSmooth: 2.4.3? – Legend

2

Lambda giảm.

from functools import reduce #you won't need this in Python 2 
reduce(set.intersection, [[1, 2, 3, 4], [2, 3, 4], [3, 4, 5, 6, 7]]) 
+0

bạn yêu cầu một danh sách các thiết lập, điều này sẽ không nói rằng 'giao lộ descriptor yêu cầu thiết lập' – tj89

2

@ user3917838

Nice và đơn giản nhưng cần một số đúc để làm cho nó làm việc và đưa ra một danh sách như một kết quả. Nó sẽ giống như thế:

list(reduce(set.intersection, [set(item) for item in d ]))

nơi:

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]

Và kết quả là:

[3, 4]

Ít nhất bằng Python 3.4

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