2010-06-01 22 views
6

cách dễ nhất để lấy giao điểm của các danh sách N-nhiều trong python là gì?lấy giao điểm của các danh sách N-nhiều trong trăn

nếu tôi có hai danh sách a, b, tôi biết tôi có thể làm:

a = set(a) 
b = set(b) 
intersect = a.intersection(b) 

nhưng tôi muốn làm một cái gì đó giống như một & b & c & d & ... cho một thiết lập tùy ý danh sách (lý tưởng là không chuyển đổi thành tập đầu tiên, nhưng nếu đó là cách dễ nhất/hiệu quả nhất, tôi có thể giải quyết vấn đề đó.)

Tức là Tôi muốn viết một chức năng giao nhau (* args) mà sẽ làm điều đó cho nhiều tùy ý một cách hiệu quả. Cách dễ nhất để làm điều đó là gì?

EDIT: Giải pháp của riêng tôi giảm (set.intersection, [a, b, c]) - có tốt không?

cảm ơn.

+0

Trên 'reduce()', nó không chính xác là ý tưởng hay nhất vì nó bị loại bỏ trong Python 3. Nó cũng chậm hơn so với những gì tôi đã nghe, so với vòng lặp for. –

+0

Nhân bản: http://stackoverflow.com/questions/2893500/take-the-intersection-of-an-arbitrary-number-of-lists-in-python –

+0

@Xavier: 'từ functools nhập khẩu giảm'. Nó bị xóa khỏi 'nội trang', nó không bị loại bỏ hoàn toàn. Ngoài ra, những gì bạn đã nghe về tốc độ của nó là rất không chính xác: nó có thể nhanh hơn hoặc chậm hơn nhiều so với vòng lặp for. – tzot

Trả lời

13

Tính năng này hoạt động cho 1 hoặc nhiều danh sách. Trường hợp 0 ​​danh sách không phải là dễ dàng như vậy, bởi vì nó sẽ phải trả về một tập hợp chứa tất cả các giá trị có thể.

def intersection(first, *others): 
    return set(first).intersection(*others) 
+0

Đẹp. Thực sự đơn giản. –

+0

Và do đó, vẻ đẹp của việc sử dụng tích hợp sẵn. – jathanism

2

này làm việc với 1 hoặc nhiều danh sách và không sử dụng nhiều thông số:

>>> def intersection(*listas): 
...  return set(listas[0]).intersection(*listas[1:]) 
...  
>>> intersection([1,2,3,4],[4,5,6],[2,4,5],[1,4,8]) 
set([4]) 
>>> intersection([1,2,3,4]) 
set([1, 2, 3, 4]) 
>>> 

Không chắc đây là tốt hơn so với câu trả lời khác, dù sao.

2
lists = [[5,4,3], [4,2], [6,2,3,4]] 

try: 
    # the following line makes one intersection too much, but I don't think 
    # this hurts performance noticably. 
    intersected = set(lists[0]).intersection(*lists) 
except ValueError: 
    # no lists[0] 
    intersected = set() 

print intersected   # set([4]) 

Bộ có thể được giao với bất kỳ lần lặp nào, không cần phải chuyển đổi nó thành bộ trước.

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