2011-10-13 35 views
21

tôi cần phải làm một cái gì đó là chức năng tương đương như sau:Chức năng bản đồ của Python có thể gọi hàm thành viên đối tượng không?

for foo in foos: 
    bar = foo.get_bar() 
    # Do something with bar 

bản năng đầu tiên của tôi là sử dụng map, nhưng điều này không làm việc:

for bar in map(get_bar, foos): 
    # Do something with bar 

phải là những gì tôi đang cố gắng để hoàn thành có thể với map? Tôi có cần phải sử dụng tính năng đọc danh sách để thay thế không? Thành ngữ Pythonic nhất cho điều này là gì?

+3

Tại sao bạn không chỉ sử dụng tính năng hiểu danh sách? – agf

Trả lời

35

hoặc với lambda:

for bar in map(lambda foo: foo.get_bar(), foos): 

hoặc với methodcaller:

import operator 
get_bar = operator.methodcaller('get_bar') 
for bar in map(get_bar, foos): 

hoặc với một biểu thức máy phát điện:

for bar in (foo.get_bar() for foo in foos): 
+8

Theo thứ tự ngược lại về cách thức chúng là Pythonic. – agf

+12

Ngoài ra, 'map (Foo.get_bar, foos)' trong đó 'Foo' là lớp của các đối tượng trong' foos'. – agf

+0

Tôi quyết định đi với lambda kể từ khi tôi nhận ra rằng tôi cần phải làm điều này chuyển đổi một vài nơi trong mã, và 'Bar' cần phải được xâu chuỗi và hạ thấp. :) –

7

Bạn muốn operator.methodcaller(). Hoặc, tất nhiên, một danh sách hoặc máy phát hiểu.

+0

Tôi đoán khả năng hiểu danh sách được ưu tiên trong các phiên bản Python mới hơn, đúng không? Tôi sẽ vui lòng chấp nhận câu trả lời của bạn nếu bạn cập nhật nó để bao gồm mã mẫu sử dụng LC cho ví dụ của tôi. :) –

+0

@JoshGlover "phiên bản mới hơn của Python"? Họ quay trở lại ít nhất là 2,3. – agf

+0

Việc hiểu danh sách được thêm vào trong Python 2.0. –

1

mã sửa đổi này sẽ làm việc:

for bar in map(lambda f: f.get_bar(), foos): 
# Do something with bar 

Bạn cung cấp hàm lambda tại đây. Đơn giản chỉ cần cung cấp get_bar không hoạt động vì nó chỉ có thể truy cập thông qua một thể hiện của lớp (f.get_bar()), không bao giờ do chính nó.

1

Bạn có thể sử dụng lambda

for bar in map(lambda foo: foo.get_bar(), foos): 
    # Do something with bar 
1

Tôi nghĩ rằng cách sạch nhất là từ bỏ các for -loop hoàn toàn và sử dụng một danh sách hiểu:

bars = [foo.get_bar() for foo in foos] 

Câu trả lời này là gần với một số khác câu trả lời nhưng khác với danh sách thực sự được trả về và không được sử dụng trong vòng lặp tiếp theo. Tùy thuộc vào những gì bạn làm với bars, bạn có thể sử dụng danh sách hiểu ở đó.

Tôi không nghĩ rằng chức năng map với lambdas có thể đọc được, ngoài chi phí cho map là đáng kể.

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