2012-04-08 50 views
16

Tôi đang cố gắng tìm ra cách so sánh một số danh sách để tìm các thành phần phổ biến. Ví dụ:Cách tìm các phần tử phổ biến trong danh sách các danh sách?

p=[ [1,2,3], 
    [1,9,9], 
     .. 
     .. 
    [1,2,4] 

>> print common(p) 
>> [1] 

Bây giờ nếu tôi biết số phần tử tôi có thể làm comparions như:

for a in b: 
    for c in d: 
    for x in y: 
... 

nhưng điều đó sẽ không làm việc nếu tôi không biết có bao nhiêu yếu tố p có. Tôi đã xem xét giải pháp này so sánh hai danh sách https://stackoverflow.com/a/1388864/1320800

nhưng sau khi dành 4 giờ cố gắng tìm cách làm cho đệ quy đó, một giải pháp vẫn giúp tôi được giúp đỡ rất nhiều!

+0

bản sao có thể có của [Python: Cách tìm giao điểm danh sách?] (Http://stackoverflow.com/questions/3697432/python-how-to-find-list-intersection) –

+0

giải pháp của bạn có phải đệ quy không? Bạn có thể sử dụng các hàm 'intersect' được xây dựng sẵn (có nghĩa là, đây là bài tập về nhà?)? –

+0

Tôi không biết rằng thuật ngữ thích hợp là "giao lộ" nên cảm ơn vì điều đó. Nó sẽ giúp tôi nhìn vào nó nhiều hơn.Bây giờ, nó không phải đệ quy nhưng chúng tôi vừa học về đệ quy nên tôi nghĩ rằng có lẽ tôi sẽ phải so sánh p [0] và p [1] và sau đó cung cấp kết quả cho phần còn lại của các phần tử, đó là lý do tại sao tôi nghĩ rằng có lẽ nó sẽ là một giải pháp đệ quy – 8bits

Trả lời

33

Bạn đang tìm kiếm các giao bộ của tất cả các danh sách phụ, và các loại dữ liệu bạn nên sử dụng cho các hoạt động thiết lập là một tập hợp:

result = set(p[0]) 
for s in p[1:]: 
    result.intersection_update(s) 
print result 
+2

+1 để sử dụng các bộ trong đó các bộ là kiểu dữ liệu thích hợp. –

+0

Cảm ơn bạn đã trả lời .. Tôi không biết gì về bộ nên tôi sẽ nghiên cứu thêm. Tuy nhiên từ một thử nghiệm sơ bộ p = [[1,2,3], [1,3], [8,1]] giải pháp bạn đề xuất thay vì [1] nó trả về [8,1]? – 8bits

+0

@ user1320800: Phiên bản đầu tiên của câu trả lời này có một câu lệnh 'print' sai cuối cùng. Tất nhiên chúng ta phải in 'kết quả', không phải' s'. –

1
reduce(lambda x, y: x & y, (set(i) for i in p)) 
+1

'reduce' không được coi là" Pythonic "của nhiều người. Ngoài ra, phiên bản của bạn yêu cầu mỗi danh sách phải được chuyển đổi thành một tập hợp và một bộ mới bổ sung sẽ là tạo ra cho mỗi giao lộ.Phiên bản của Sven chỉ tạo ra một bộ – agf

+0

@agf: Đã hiểu, tuy nhiên, nó là một giải pháp làm việc (mặc dù là một giải pháp không hiệu quả) –

1
p=[ [1,2,3], 
    [1,9,9], 
    [1,2,4]] 

ans = [ele[0] for ele in zip(*p) if len(set(ele)) == 1] 

Kết quả:

>>> ans 
[1] 
+1

Hãy thử với p = [[1,2], [2,1] ] Hoặc thậm chí p = [[1,2], [2]] – DSM

+0

Mã của tôi chỉ hoạt động, nếu chúng ta xem xét tất cả các thành phần chung cũng ở cùng một vị trí, đó là toàn bộ ý nghĩa của mã zip (* Đó là những gì tôi nghĩ OP muốn, nhưng đọc lại bài đăng, tôi có lẽ đã hiểu lầm.Tôi cũng giả định rằng mỗi danh sách con có cùng độ dài – Akavall

+0

Ngoài ra, 'zip' sẽ thả các phần tử nếu các danh sách khác nhau về độ dài –

4

Tại sao không chỉ:

set.intersection(*map(set, p)) 

Kết quả:

set([1]) 

Hoặc như thế này:

ip = iter(p) 
s = set(next(ip)) 
s.intersection(*ip) 

Kết quả:

set([1]) 

chỉnh sửa:

sao chép từ giao diện điều khiển:

>>> p = [[1,2,3], [1,9,9], [1,2,4]] 
>>> set.intersection(*map(set, p)) 
set([1]) 
>>> ip = iter(p) 
>>> s = set(next(ip)) 
>>> s.intersection(*ip) 
set([1]) 
+0

Tôi không biết mình có thiếu gì hay không nhưng chuyển p = [[1,2,3], [1,9,9], [1,2,4]] dường như không hoạt động – 8bits

+0

@ 8bits: Vui lòng xem chỉnh sửa của tôi. – pillmuncher

10
>>> p=[ [1,2,3], 
    [1,9,9], 
    [1,2,4]] 
>>> set(p[0]).intersection(*p) 
set([1]) 
1

Một giải pháp đơn giản (một dòng) là:

set.intersection(*[set(list) for list in p]) 
0

Bạn đang tìm kiếm các giao bộ của tất cả các danh sách phụ, và các loại dữ liệu bạn nên sử dụng cho các hoạt động thiết lập là một tập hợp:

result = set(p[0]) 
for s in p[1:]: 
    result.intersection_update(s) 
print result 

Tuy nhiên, có giới hạn 10 danh sách trong danh sách. Bất cứ điều gì lớn hơn gây ra 'kết quả' danh sách được ra khỏi trật tự. Giả sử bạn đã tạo 'kết quả' thành một danh sách theo số list(result).

Đảm bảo bạn result.sort() để đảm bảo rằng nó được đặt hàng nếu bạn phụ thuộc vào nó theo cách đó.

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