2012-06-11 39 views
185
map(function, iterable, ...) 

Áp dụng chức năng cho mọi mục có thể lặp lại và trả về danh sách kết quả. Nếu các đối số lặp lại bổ sung được truyền, hàm phải lấy nhiều đối số đó và được áp dụng cho các mục từ tất cả các vòng lặp song song.Hiểu chức năng bản đồ

Nếu một lần lặp lại ngắn hơn giá trị khác, nó được giả định là được mở rộng bằng Không có mục nào.

Nếu hàm là None, hàm nhận dạng được giả định; nếu có nhiều đối số, map() trả về một danh sách chứa các bộ chứa các mục tương ứng từ tất cả các lần lặp (một loại hoạt động chuyển tiếp).

Đối số có thể lặp lại có thể là một chuỗi hoặc bất kỳ đối tượng có thể lặp lại nào; kết quả luôn là danh sách.

Điều này đóng vai trò gì trong việc tạo ra một sản phẩm Descartes?

content = map(tuple, array) 

Hiệu ứng nào khiến bộ đồ ở bất cứ đâu trong đó? Tôi cũng nhận thấy rằng không có chức năng bản đồ, đầu ra là abc và với nó, nó là a, b, c.

Tôi muốn hiểu đầy đủ chức năng này. Các định nghĩa tham chiếu cũng khó hiểu. Quá nhiều lông tơ ưa thích.

+1

Bạn thực sự muốn đạt được điều gì và tại sao cụ thể bạn muốn sử dụng 'bản đồ'? –

+0

để bản đồ về cơ bản chỉ áp dụng điều gì đó cho mọi phần tử? –

+3

@WebMaster có, mỗi câu đầu tiên trong tài liệu mà bạn đã dán - "Áp dụng chức năng cho mọi mục có thể lặp lại". Phần còn lại của đoạn này là về các trường hợp phức tạp hơn - như 'map (None, a, b, c)' xuất hiện để làm 'zip (a, b, c)'. Nhưng bạn rất hiếm khi thấy rằng trong thực tế, chính xác vì cuộc gọi 'zip' là tương đương. – lvc

Trả lời

271

map không phải là đặc biệt là pythonic. Tôi sẽ khuyên bạn sử dụng comprehensions danh sách thay vì:

map(f, iterable) 

về cơ bản là tương đương với:

[f(x) for x in iterable] 

map trên riêng của mình không thể làm được một sản phẩm Descartes, vì chiều dài của danh sách sản lượng của nó luôn luôn là như nhau làm danh sách đầu vào của nó. Bạn trivially có thể làm ra một sản phẩm Descartes với một sự hiểu biết danh sách mặc dù:

[(a, b) for a in iterable_a for b in iterable_b] 

Cú pháp là một chút bối rối - đó là về cơ bản tương đương với:

result = [] 
for a in iterable_a: 
    for b in iterable_b: 
     result.append((a, b)) 
+5

Tôi tìm thấy bằng cách sử dụng 'bản đồ' ít chi tiết hơn so với việc hiểu danh sách, ít nhất là đối với trường hợp bạn đang trình diễn. – marbel

+1

Tôi làm cách nào để sử dụng bản đồ cho các thuộc tính? 'Map' tương đương với' [v .__ name__ cho v in (object, str)] 'là gì? –

+0

@ASz Làm thế nào về 'map (lambda v: v .__ name__, list)'? –

64

map không liên quan đến sản phẩm Descartes chút nào, mặc dù tôi tưởng tượng ai đó giỏi trong lập trình hàm có thể tìm ra cách để tạo ra một cách sử dụng map.

map bằng Python 3 là tương đương với điều này:

def map(func, iterable): 
    for i in iterable: 
     yield func(i) 

và sự khác biệt duy trong Python 2 là nó sẽ xây dựng một danh sách đầy đủ các kết quả trả lại tất cả cùng một lúc thay vì yield ing.

Mặc dù ước Python thường thích comprehensions danh sách (hoặc biểu thức máy phát điện) để đạt được kết quả tương tự như một cuộc gọi đến map, đặc biệt là nếu bạn đang sử dụng một biểu thức lambda như là đối số đầu tiên:

[func(i) for i in iterable] 

Là một ví dụ về những gì bạn yêu cầu trong các nhận xét về câu hỏi - "biến chuỗi thành một mảng", bởi 'mảng' bạn có thể muốn hoặc một bộ hoặc danh sách (cả hai đều hoạt động giống như mảng từ các ngôn ngữ khác) -

>>> a = "hello, world" 
>>> list(a) 
['h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd'] 
>>> tuple(a) 
('h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd') 

Một ứng dụng của map đây sẽ là nếu bạn bắt đầu với một danh sách các chuỗi thay vì một chuỗi duy nhất - map thể listify tất cả chúng riêng lẻ:

>>> a = ["foo", "bar", "baz"] 
>>> list(map(list, a)) 
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']] 

Lưu ý rằng map(list, a) tương đương bằng Python 2, nhưng trong Python 3 bạn cần cuộc gọi list nếu bạn muốn làm bất cứ điều gì khác hơn là nạp nó vào một vòng lặp for (hoặc một hàm xử lý như sum chỉ cần lặp lại và không phải là một chuỗi).Nhưng cũng lưu ý một lần nữa rằng một danh sách hiểu được thường ưa thích:

>>> [list(b) for b in a] 
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']] 
+0

bản đồ (vui vẻ x -> (x, x)) dường như không khó hiểu ... (mặc dù việc có được một sản phẩm thật ra khỏi bản đồ sẽ là không thể, bất kỳ bản đồ nào tạo ra luôn luôn là một dạng của một danh sách) –

22

map tạo ra một danh sách mới bằng cách áp dụng một chức năng để mọi yếu tố của nguồn:

xs = [1, 2, 3] 

# all of those are equivalent — the output is [2, 4, 6] 
# 1. map 
ys = map(lambda x: x * 2, xs) 
# 2. list comprehension 
ys = [x * 2 for x in xs] 
# 3. explicit loop 
ys = [] 
for x in xs: 
    ys.append(x * 2) 

n-ary map tương đương với nén đầu vào lặp lại với nhau và sau đó áp dụng hàm chuyển đổi trên mọi phần tử của danh sách được nén trung gian đó. Đó là không một sản phẩm Descartes:

xs = [1, 2, 3] 
ys = [2, 4, 6] 

def f(x, y): 
    return (x * 2, y // 2) 

# output: [(2, 1), (4, 2), (6, 3)] 
# 1. map 
zs = map(f, xs, ys) 
# 2. list comp 
zs = [f(x, y) for x, y in zip(xs, ys)] 
# 3. explicit loop 
zs = [] 
for x, y in zip(xs, ys): 
    zs.append(f(x, y)) 

Tôi đã sử dụng zip ở đây, nhưng map hành vi thực sự hơi khác khi iterables không phải là kích thước tương tự - như đã nêu trong tài liệu hướng dẫn của nó, nó mở rộng iterables chứa None.

+0

phức tạp , cố gắng tiêu hóa bài đăng này –

+1

@WebMaster Điều gì phức tạp về nó? –

+0

Câu trả lời hay nhất theo ý kiến ​​của tôi. Sử dụng lambda trong ví dụ như một hàm làm cho nó rất rõ ràng. – sheldonzy

17

Đơn giản hóa một chút, bạn có thể tưởng tượng map() làm điều gì đó như thế này:

def mymap(func, lst): 
    result = [] 
    for e in lst: 
     result.append(func(e)) 
    return result 

như bạn thấy, phải mất một chức năng và một danh sách, và trả về một danh sách mới với kết quả của việc áp dụng chức năng cho mỗi các yếu tố trong danh sách đầu vào. Tôi nói "đơn giản hóa một chút" bởi vì trong thực tế map() có thể xử lý nhiều hơn một iterable:

Nếu thêm lập luận iterable được thông qua, chức năng phải mất rằng nhiều tranh cãi và được áp dụng cho các mặt hàng từ khắp nơi iterables song song . Nếu một vòng lặp có thể lặp lại ngắn hơn, nó được giả định là được mở rộng với Không có mục nào.

Đối với phần thứ hai trong câu hỏi: Vai trò này sẽ tạo ra sản phẩm Descartes? tốt, map()thể được sử dụng để tạo ra các sản phẩm Descartes của một danh sách như thế này:

lst = [1, 2, 3, 4, 5] 

from operator import add 
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst)) 

...Nhưng để nói sự thật, sử dụng product() là một cách đơn giản hơn nhiều và tự nhiên để giải quyết vấn đề:

from itertools import product 
list(product(lst, lst)) 

Dù bằng cách nào, kết quả là sản phẩm Cartesian của lst như đã định nghĩa ở trên:

[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), 
(2, 1), (2, 2), (2, 3), (2, 4), (2, 5), 
(3, 1), (3, 2), (3, 3), (3, 4), (3, 5), 
(4, 1), (4, 2), (4, 3), (4, 4), (4, 5), 
(5, 1), (5, 2), (5, 3), (5, 4), (5, 5)] 
6

Hope điều này giúp ai đó mà là mới để lập trình và python:

chức năng map() là có để áp dụng các thủ tục tương tự cho mọi item trong một iterable data structure, như lists, generators, strings và các nội dung khác.

Cho phép xem xét một ví dụ: map() thể iterate trên mỗi item trong một list và áp dụng một function cho mỗi item, hơn nó sẽ return (cung cấp cho bạn trở lại) các new list.

Giả sử bạn có số function có số (integer), cộng 1 vào số đó và trả lại số đó.

def add_one(num): 
    new_num = num + 1 
    return new_num 

Bạn cũng có một list số (integers)

my_list = [1,3,6,7,8,10] 

nếu bạn muốn increment mỗi số (integer) trong list, bạn có thể làm như sau:

map(add_one, my_list) 

Lưu ý: Tối thiểu map() cần hai arguments. Đầu tiên là tên function và thứ hai giống như một số list.

kết quả của ví dụ trên, map() sẽ cho bạn trở lại này:

[2, 4, 7, 8, 9, 11] 

Cho phép xem một số điều thú vị khác map() có thể làm. map() có thể mất nhiều iterables (lists, strings, etc) và vượt qua một element từ mỗi list (Tôi đang sử dụng danh sách làm ví dụ) cho function làm argument.

Chúng tôi đã liệt kê sau đây:

list_one = [1, 2, 3, 4, 5] 
list_two = [11, 12, 13, 14, 15] 
list_three = [21, 22, 23, 24, 25] 

map() có thể làm cho bạn một new list chứa việc bổ sung các yếu tố tại một cụ index (vị trí).

Bây giờ hãy nhớ map(), cần function.

def add_from_three_lists(num1, num2, num3): 
    total_num = num1 + num2 + num3 
    return total_num 

bây giờ cho phép sử dụng map() chức năng

map(add_from_three_lists, list_one, List_two, list_three) 

và bạn sẽ nhận được:

[33, 36, 39, 42, 45] 

NHỚ:
Trong python2 map(), sẽ iterate (đi qua các yếu tố của lists) accordi ng dài nhất list và vượt qua NoneType để thực hiện chức năng cho lists ngắn hơn, do đó, function của bạn nên tìm kiếm NoneType và xử lý chúng, nếu không bạn sẽ nhận được errors. Trong python 3 map() sẽ chỉ đi theo ngắn nhất list. Ngoài ra, trong Python 3, map() trả về một trình lặp, không phải danh sách.

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