web-dev-qa-db-ja.com

「for」ループとマップの違い

タイトルから、はい、違いがあります。ここで私のシナリオに適用します:クラスDummyを考えてみましょう:

class Dummy:
    def __init__(self):
        self.attached = []

    def attach_item(self, item):
        self.attached.append(item)

これを使用する場合:

D = Dummy()
items = [1, 2, 3, 4]
for item in items:
    D.attach_item(item)

確かにD.attached = [1, 2, 3, 4]を取得します。ただし、関数attach_itemitemsにマップすると、D.attachedは空のままになります。

map(D.attach_item, items)

何してるの?

42
Mathieu

興味深い答えがある非常に興味深い質問。

map関数は、反復可能なMapオブジェクトを返します。 mapは計算を遅延して実行しているため、そのオブジェクトを反復しない限り、関数は呼び出されません。

その場合:

x = map(D.attach_item, items)
for i in x:
    continue

期待される結果が表示されます。

53

mapは、反復子のみを作成します。アイテムをD.attachedに追加するには、繰り返し処理する必要があります。このような:

D = Dummy()
items = [1, 2, 3, 4]
list(map(D.attach_item, items))

うん、あなたのコードでそれをしないでください:)しかし、この例は理解するのに役立ちます。

16
Lev Zakharov

ドキュメント の引用

Iterableのすべてのアイテムに関数を適用するイテレータを返し、結果を生成します。

つまり、イテレータを収集する必要があります。

list(map(D.attach_item, items))

> [None, None, None, None]

うーん、奇妙な。なぜなし、なし、...

はい、マップステートメント内の任意のループを変換できますが、必ずしも便利ではありません。 Mapはパラメーターを受け取り、それを使用して(ほとんどの場合)副作用なしでそれを返します!以下に例を示します。

def add(a):
    return a + 3
list(map(add, items))

> [4, 5, 6, 7]

filter のような他の関数と組み合わせると、真の力が得られます

def add(a):
    return a + 3
def odd(a):
    return a % 2 == 1
list(map(add, filter(odd, items)))

> [4, 6]
9
hellow