マップ機能について


311
map(function, iterable, ...)

イテラブルのすべてのアイテムに関数を適用し、結果のリストを返します。追加の反復可能な引数が渡された場合、関数はその数の引数を取り、すべての反復可能なアイテムのアイテムに並行して適用されます。

1つのイテラブルが別のイテラブルよりも短い場合は、Noneアイテムで拡張されていると見なされます。

functionがのNone場合、恒等関数と見なされます。複数の引数がある場合map()、すべての反復可能オブジェクトからの対応する項目を含むタプルで構成されるリストを返します(一種の転置演算)。

反復可能な引数は、シーケンスまたは任意の反復可能なオブジェクトです。結果は常にリストです。

デカルト積を作る上でこれはどのような役割を果たしますか?

content = map(tuple, array)

そこにタプルを配置するとどのような影響がありますか?また、map関数がなければ出力がabcあり、それを使用するとa, b, cです。

この機能を十分に理解したい。参照の定義も理解しにくいです。派手すぎる綿毛。


2
実際に何を達成したいのか、特に具体的に使用したいのはなぜmapですか?
クリスハーパー

3
@WebMasterはい、あなたが貼り付けたドキュメントの最初の文ごとに-「反復可能なすべてのアイテムに関数を適用します」。段落の残りの部分は、より複雑なケースについてです-のようにmap(None, a, b, c)判明zip(a, b, c)。ただし、zip呼び出しが同等であるため、実際にそれが見られることはほとんどありません。
lvc

9
私はpythonを学ぶために一生懸命努力しており、いつでもpython.orgで定義を開いています。最初の文の後、何もわかりません。よし。ありがとうございました。
Webマスター

2
tuple反復可能関数を取り、同じ要素を持つタプルを提供する関数です(まあ、それよりも微妙ですが、関数のように動作します)。これtuple([1, 2, 3])はと同等(1, 2, 3)です。の場合map(tuple, array)array反復可能な反復可能オブジェクト(リストのリストと考えてください)であり、タプルに変換された各内部リストを返します。
lvc

1
一般的に、これは最も重要な機能のドキュメントの最初の文です。それを理解すれば、その要点がわかります。それの残りの部分は非常に詳細での動作を指定し、そのうちのいくつかはしますと起動するビット不透明で、あなたはあなたが見る前に、それに基づいて奇数イディオムに遭遇する必要があるかもしれません「ああ、手段どのようなことを!」。しかし、いくつかのビルトインについてその電球の瞬間を手に入れたら、ドキュメントをもう少し簡単に理解できるようになるはずです。
lvc

回答:


441

map特にpythonicではありません。代わりにリスト内包表記を使用することをお勧めします。

map(f, iterable)

基本的に以下と同等です:

[f(x) for x in iterable]

map出力リストの長さは常に入力リストと同じであるため、それだけではデカルト積を実行できません。ただし、リスト内包表記を使用してデカルト積を簡単に作成できます。

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

構文は少し混乱します-それは基本的に以下と同等です:

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

36
map少なくともあなたが実証している場合については、リスト内包表記よりもはるかに冗長ではないことがわかります。
marbel

1
プロパティにマップを使用するにはどうすればよいですか?map同等のものは何[v.__name__ for v in (object, str)]ですか?
A Sz

@ASzどうmap(lambda v: v.__name__, list)ですか?
キリアン2017年

10
マップは、関数を呼び出す..速く、それはイテレータの長さに基づいて関数を呼び出していないためである持っているオーバーヘッド..ウォッチ午前6時 youtube.com/watch?v=SiXyyOA6RZg&t=813s
anati

1
@anati 正確に関数呼び出しのオーバーヘッドが原因で、内包より速い場合もあればそうでない場合もあると思いましmapたか?特に、私が学んだ経験則では、使用時に追加の関数呼び出しを導入する必要がある場合、理解が速くなるということです。たとえば、追加の関数呼び出しが原因で、が、、さらにでさえも遅いと信じるようになりました。mapmap(lambda foo: foo.bar, my_list)foo.bar for foo in my_listmap(operator.add, my_list_of_pairs)x + y for x, y in my_list_of_pairs
mtraceur 2018

86

map関数型プログラミングに精通している誰かが、を使用して生成する方法を理解するのが不可能なことを思い付くかもしれませんが、デカルト積とはまったく関係ありませんmap

map Python 3では、これと同等です。

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

Python 2の唯一の違いは、結果の完全なリストが作成され、yieldING ではなく一度にすべてが返されることです。

Pythonの規則では通常map、特に最初の引数としてラムダ式を使用している場合、への呼び出しと同じ結果を得るにはリスト内包表記(またはジェネレータ式)が優先されます。

[func(i) for i in iterable]

「文字列を配列に変換する」という質問のコメントの例として、「配列」ではタプルまたはリストのいずれかが必要です(どちらも他の言語の配列と少し似ています) -

 >>> 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')

mapここでの使用法は、単一の文字列ではなく文字列のリストから始める場合です- mapそれらすべてを個別にリスト化できます。

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

map(list, a)Pythonの2に相当しますが、Pythonの3に必要なlistあなたに飼料以外の何でもそれをしたい場合は、コールをfor(のようなまたは処理機能ループsumそれが唯一のシーケンス反復可能、とされていない必要があります)。しかし、リスト内包表記が通常好まれることにも注意してください。

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

map(fun x->(x、x))は理解しにくいように見えます...(真のデカルト積をマップから取得することは不可能ですが、マップが生成するものは常に何らかの形式のリストです)
クリストファー・ミシンスキー

36

map ソースのすべての要素に関数を適用して、新しいリストを作成します。

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は、入力反復可能オブジェクトをまとめて圧縮し、その中間圧縮リストのすべての要素に変換関数を適用することと同じです。これはデカルト積ではありません

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))

私はzipここで使用しましたが、mapイテラブルが同じサイズでない場合、実際には動作が少し異なりますNone。そのドキュメントに記載されているように、イテラブルを拡張してを含みます。


1
複雑で、この投稿を消化しようとしてい
ます

1
@WebMasterそれについて何が複雑ですか?
ジョシーカルデロン

私の意見では最良の回答です。例のラムダを関数として使用すると、非常に明確になります。
シェルドンジー2018

残念ながらこれらすべては同等ではありません-出力は[2,4,6]リスト内包と明示的なループの出力ですが、マップはマップオブジェクトを返します-たとえば、これを取得します:<map at 0x123a49978>これをリストに強制する必要があります。
leerssej

20

少し単純化すると、次のmap()ようなことを想像できます。

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

ご覧のとおり、関数とリストを受け取り、入力リストの各要素に関数を適用した結果を含む新しいリストを返します。「少し単純化する」と言ったのは、実際にmap()複数の反復可能オブジェクトを処理できるためです。

追加の反復可能な引数が渡された場合、関数はその多くの引数を取り、すべての反復可能なアイテムのアイテムに並行して適用されます。1つのイテラブルが別のイテラブルよりも短い場合、Noneアイテムで拡張されていると見なされます。

質問の2番目の部分について:デカルト積を作成する上でこれはどのような役割を果たしますか?まあ、このようなリストのデカルト積を生成するために使用map() できます:

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

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

...しかし、実を言うproduct()と、問題を解決するには、使用する方がはるかに簡単で自然な方法です。

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

いずれにせよ、結果はlst上記で定義されたデカルト積です。

[(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)]

17

このmap()関数は、リスト、ジェネレーター、文字列などの反復可能なデータ構造内のすべてのアイテムに同じ手順を適用するためのものです。

例を見てみましょう。 map()リスト内のすべてのアイテムを反復処理し、各アイテムに関数を適用すると、新しいリストが返されます(元に戻すことができます)。

数値を受け取り、その数値に1を加算して返す関数があるとします。

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

番号のリストもあります:

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

リスト内のすべての数値をインクリメントする場合は、以下を実行できます。

>>> map(add_one, my_list)
[2, 4, 7, 8, 9, 11]

注:少なくともmap()2つの引数が必要です。最初に関数名、次にリストのようなもの。

他のクールなことmap()ができることを見てみましょう。 map()複数のイテラブル(リスト、文字列など)を取り、各イテラブルから要素を引数として関数に渡すことができます。

3つのリストがあります。

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

map() 特定のインデックスで要素の追加を保持する新しいリストを作成できます。

覚えておいてくださいmap()、関数が必要です。今回は組み込みsum()関数を使用します。実行map()すると、次の結果が得られます。

>>> map(sum, list_one, list_two, list_three)
[33, 36, 39, 42, 45]

注意:
Python 2 map()では、最長のリストに従って反復し(リストの要素を通過)None、短いリストの関数に渡すため、関数はNoneそれらを探して処理する必要があります。そうしないと、エラーが発生します。Python 3 map()では、最短のリストで終了すると停止します。また、Python 3ではmap()、リストではなくイテレーターを返します。


8

Python3-map(func、反復可能)

(@BlooBはちょっとそれを言及したが)完全に言及されていなかったことの一つは、そのマップが返すマップオブジェクトではありませんリスト。これは、初期化と反復の時間パフォーマンスに関しては大きな違いです。次の2つのテストを検討してください。

import time
def test1(iterable):
    a = time.clock()
    map(str, iterable)
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


def test2(iterable):
    a = time.clock()
    [ x for x in map(str, iterable)]
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


test1(range(2000000))  # Prints ~1.7e-5s   ~8s
test2(range(2000000))  # Prints ~9s        ~8s

ご覧のとおり、マップ関数の初期化にはほとんど時間がかかりません。ただし、マップオブジェクトを反復する場合は、単に反復可能オブジェクトを反復する場合よりも時間がかかります。つまり、map()に渡された関数は、反復で要素に到達するまで各要素に適用されません。リストが必要な場合は、リスト内包表記を使用してください。forループで反復する予定があり、ある時点で中断する場合は、mapを使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.