map関数の使い方を徹底解説!初心者でもわかる一括変換処理の完全ガイド

 

Pythonプログラミングでリストやタプルの全要素に同じ処理を適用したい時に重宝するのが「map関数」です。「ループを書くのが面倒」「もっと効率的に処理したい」と感じる場面で非常に便利な機能ですが、「使い方がよくわからない」「いつ使えばいいの?」と悩む方も多いでしょう。この記事では、Pythonのmap関数の基本から実践的な活用法まで、豊富なサンプルコードとともに徹底解説します。

map関数とは?基本概念を理解しよう

map関数は、指定した関数をイテラブル(リスト、タプルなど)の全要素に適用して、結果を新しいイテレータとして返すPythonの組み込み関数です。「一括変換処理」を効率的に実行できます。

map関数の基本構文

map(function, iterable)
  • function: 各要素に適用する関数
  • iterable: 処理対象のデータ(リスト、タプルなど)

最もシンプルなmap関数の例

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

# 各要素を2倍にする
doubled = list(map(lambda x: x * 2, numbers))
print(doubled)  # 出力: [2, 4, 6, 8, 10]

map関数の基本的な使い方

数値の変換処理

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

# 各要素を平方する
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # 出力: [1, 4, 9, 16, 25]

# 各要素に10を加算
plus_ten = list(map(lambda x: x + 10, numbers))
print(plus_ten)  # 出力: [11, 12, 13, 14, 15]

# 各要素の平方根を計算
import math
sqrt_values = list(map(math.sqrt, [1, 4, 9, 16, 25]))
print(sqrt_values)  # 出力: [1.0, 2.0, 3.0, 4.0, 5.0]

文字列の変換処理

words = ["hello", "world", "python", "programming"]

# 文字列を大文字に変換
upper_words = list(map(str.upper, words))
print(upper_words)  # 出力: ['HELLO', 'WORLD', 'PYTHON', 'PROGRAMMING']

# 文字列の長さを取得
lengths = list(map(len, words))
print(lengths)  # 出力: [5, 5, 6, 11]

# 文字列を逆順にする
reversed_words = list(map(lambda s: s[::-1], words))
print(reversed_words)  # 出力: ['olleh', 'dlrow', 'nohtyp', 'gnimmargorp']

通常の関数を使ったmap関数

関数を定義してmapに渡す

def celsius_to_fahrenheit(celsius):
    return celsius * 9/5 + 32

def is_even(num):
    return num % 2 == 0

celsius_temps = [0, 10, 20, 30, 40]
numbers = [1, 2, 3, 4, 5, 6]

# 摂氏を華氏に変換
fahrenheit_temps = list(map(celsius_to_fahrenheit, celsius_temps))
print(fahrenheit_temps)  # 出力: [32.0, 50.0, 68.0, 86.0, 104.0]

# 偶数判定
even_checks = list(map(is_even, numbers))
print(even_checks)  # 出力: [False, True, False, True, False, True]

より複雑な変換関数

def format_currency(amount):
    return f"¥{amount:,}"

def calculate_tax(price, tax_rate=0.1):
    return price * (1 + tax_rate)

prices = [1000, 2500, 5000, 12000]

# 通貨形式でフォーマット
formatted_prices = list(map(format_currency, prices))
print(formatted_prices)  # 出力: ['¥1,000', '¥2,500', '¥5,000', '¥12,000']

# 税込み価格を計算
tax_included = list(map(lambda p: calculate_tax(p), prices))
print(tax_included)  # 出力: [1100.0, 2750.0, 5500.0, 13200.0]

複数のイテラブルを処理

2つのリストを同時に処理

numbers1 = [1, 2, 3, 4, 5]
numbers2 = [10, 20, 30, 40, 50]

# 対応する要素を加算
sums = list(map(lambda x, y: x + y, numbers1, numbers2))
print(sums)  # 出力: [11, 22, 33, 44, 55]

# 対応する要素を乗算
products = list(map(lambda x, y: x * y, numbers1, numbers2))
print(products)  # 出力: [10, 40, 90, 160, 250]

3つ以上のイテラブルを処理

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]

# 3つのリストの要素を合計
triple_sum = list(map(lambda x, y, z: x + y + z, a, b, c))
print(triple_sum)  # 出力: [12, 15, 18]

# 座標データの処理
x_coords = [1, 2, 3]
y_coords = [4, 5, 6]
z_coords = [7, 8, 9]

# 3D座標を文字列に変換
coordinates = list(map(lambda x, y, z: f"({x}, {y}, {z})", x_coords, y_coords, z_coords))
print(coordinates)  # 出力: ['(1, 4, 7)', '(2, 5, 8)', '(3, 6, 9)']

辞書とmap関数

辞書のリストを変換

students = [
    {"name": "Alice", "score": 85},
    {"name": "Bob", "score": 92},
    {"name": "Charlie", "score": 78}
]

# 名前のみを抽出
names = list(map(lambda s: s["name"], students))
print(names)  # 出力: ['Alice', 'Bob', 'Charlie']

# 成績を10点アップ
boosted_scores = list(map(lambda s: {**s, "score": s["score"] + 10}, students))
print(boosted_scores)  # 出力: [{'name': 'Alice', 'score': 95}, ...]

# 合格判定を追加
with_result = list(map(lambda s: {**s, "passed": s["score"] >= 80}, students))
print(with_result)

辞書の値を変換

data = {"a": 1, "b": 2, "c": 3, "d": 4}

# 辞書の値を2倍にする
doubled_values = dict(map(lambda item: (item[0], item[1] * 2), data.items()))
print(doubled_values)  # 出力: {'a': 2, 'b': 4, 'c': 6, 'd': 8}

# キーを大文字に変換
upper_keys = dict(map(lambda item: (item[0].upper(), item[1]), data.items()))
print(upper_keys)  # 出力: {'A': 1, 'B': 2, 'C': 3, 'D': 4}

型変換でのmap関数活用

文字列から数値への変換

string_numbers = ["1", "2", "3", "4", "5"]

# 文字列を整数に変換
integers = list(map(int, string_numbers))
print(integers)  # 出力: [1, 2, 3, 4, 5]

# 文字列を浮動小数点数に変換
float_numbers = ["1.5", "2.7", "3.14", "4.0"]
floats = list(map(float, float_numbers))
print(floats)  # 出力: [1.5, 2.7, 3.14, 4.0]

より複雑な型変換

mixed_data = ["123", "45.6", "789", "12.34"]

# 文字列を適切な数値型に変換
def smart_convert(s):
    return int(s) if '.' not in s else float(s)

converted = list(map(smart_convert, mixed_data))
print(converted)  # 出力: [123, 45.6, 789, 12.34]

# JSON文字列をオブジェクトに変換
import json
json_strings = ['{"name": "Alice"}', '{"name": "Bob"}']
objects = list(map(json.loads, json_strings))
print(objects)  # 出力: [{'name': 'Alice'}, {'name': 'Bob'}]

map関数 vs リスト内包表記

パフォーマンスと可読性の比較

numbers = list(range(1000))

# map関数を使用
squared_map = list(map(lambda x: x ** 2, numbers))

# リスト内包表記を使用
squared_comp = [x ** 2 for x in numbers]

# 結果は同じ
print(squared_map == squared_comp)  # 出力: True

どちらを選ぶべきか

# シンプルな変換:どちらでも可
doubled_map = list(map(lambda x: x * 2, [1, 2, 3, 4, 5]))
doubled_comp = [x * 2 for x in [1, 2, 3, 4, 5]]

# 既存関数の適用:mapが適している
words = ["hello", "world"]
upper_map = list(map(str.upper, words))
upper_comp = [word.upper() for word in words]

# 条件付き変換:リスト内包表記が読みやすい
positive_doubled = [x * 2 for x in [-1, 2, -3, 4] if x > 0]

実践的なmap関数の応用例

ファイルパス処理

import os

file_paths = ["/home/user/file1.txt", "/home/user/file2.py", "/home/user/file3.md"]

# ファイル名のみを抽出
filenames = list(map(os.path.basename, file_paths))
print(filenames)  # 出力: ['file1.txt', 'file2.py', 'file3.md']

# 拡張子を除いたファイル名を取得
names_only = list(map(lambda p: os.path.splitext(os.path.basename(p))[0], file_paths))
print(names_only)  # 出力: ['file1', 'file2', 'file3']

URL処理

urls = [
    "https://example.com/page1",
    "https://example.com/page2",
    "https://example.com/page3"
]

# URLからドメイン名を抽出
from urllib.parse import urlparse
domains = list(map(lambda url: urlparse(url).netloc, urls))
print(domains)  # 出力: ['example.com', 'example.com', 'example.com']

# HTTPSをHTTPに変換
http_urls = list(map(lambda url: url.replace("https://", "http://"), urls))
print(http_urls)

データクリーニング

raw_data = ["  Alice  ", "Bob\n", "\tCharlie", "  Diana\n\t"]

# 前後の空白文字を除去
cleaned_data = list(map(str.strip, raw_data))
print(cleaned_data)  # 出力: ['Alice', 'Bob', 'Charlie', 'Diana']

# 電話番号を統一フォーマットに変換
phone_numbers = ["090-1234-5678", "09012345678", "090 1234 5678"]
def format_phone(phone):
    digits = ''.join(filter(str.isdigit, phone))
    return f"{digits[:3]}-{digits[3:7]}-{digits[7:]}"

formatted_phones = list(map(format_phone, phone_numbers))
print(formatted_phones)  # 出力: ['090-1234-5678', '090-1234-5678', '090-1234-5678']

統計処理

import statistics

test_scores = [
    [85, 90, 78, 92],
    [88, 76, 84, 89],
    [90, 95, 87, 93]
]

# 各学生の平均点を計算
averages = list(map(statistics.mean, test_scores))
print(averages)  # 出力: [86.25, 84.25, 91.25]

# 各学生の最高点を取得
max_scores = list(map(max, test_scores))
print(max_scores)  # 出力: [92, 89, 95]

# 標準偏差を計算
std_devs = list(map(statistics.stdev, test_scores))
print(std_devs)

mapとfilterの組み合わせ

データの変換と絞り込みを同時実行

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 偶数のみを抽出して2乗
squared_evens = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers)))
print(squared_evens)  # 出力: [4, 16, 36, 64, 100]

# 長い文字列のみを大文字に変換
words = ["cat", "dog", "elephant", "fish", "tiger"]
long_upper = list(map(str.upper, filter(lambda w: len(w) >= 4, words)))
print(long_upper)  # 出力: ['ELEPHANT', 'FISH', 'TIGER']

パイプライン処理

sales_records = [
    {"product": "A", "price": 1000, "quantity": 5},
    {"product": "B", "price": 1500, "quantity": 3},
    {"product": "C", "price": 800, "quantity": 7}
]

# 売上高を計算し、1000以上のもののみフォーマット
high_revenue = list(
    map(lambda item: f"{item['product']}: ¥{item['revenue']:,}",
        map(lambda item: {**item, "revenue": item["price"] * item["quantity"]},
            filter(lambda item: item["price"] * item["quantity"] >= 4000, sales_records)))
)
print(high_revenue)  # 出力: ['A: ¥5,000', 'B: ¥4,500', 'C: ¥5,600']

クラスオブジェクトとmap関数

オブジェクトのメソッド呼び出し

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def get_info(self):
        return f"{self.name} ({self.age})"
    
    def is_adult(self):
        return self.age >= 18

people = [Person("Alice", 25), Person("Bob", 17), Person("Charlie", 30)]

# 全員の情報を取得
info_list = list(map(Person.get_info, people))
print(info_list)  # 出力: ['Alice (25)', 'Bob (17)', 'Charlie (30)']

# 成人判定
adult_checks = list(map(Person.is_adult, people))
print(adult_checks)  # 出力: [True, False, True]

オブジェクトの属性アクセス

from operator import attrgetter

people = [Person("Alice", 25), Person("Bob", 17), Person("Charlie", 30)]

# 名前のみを抽出
names = list(map(attrgetter('name'), people))
print(names)  # 出力: ['Alice', 'Bob', 'Charlie']

# 年齢のみを抽出
ages = list(map(attrgetter('age'), people))
print(ages)  # 出力: [25, 17, 30]

map関数のパフォーマンス最適化

ジェネレータとしての活用

# 大量のデータを扱う場合はlistに変換せず、ジェネレータのまま使用
large_numbers = range(1000000)

# メモリ効率的な処理
squared_generator = map(lambda x: x ** 2, large_numbers)

# 必要な分だけ取得
first_10_squares = []
for i, num in enumerate(squared_generator):
    if i >= 10:
        break
    first_10_squares.append(num)

print(first_10_squares)  # 出力: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

部分適用(functools.partial)の活用

from functools import partial

def multiply(x, y):
    return x * y

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

# 2倍する関数を作成
double = partial(multiply, 2)
doubled = list(map(double, numbers))
print(doubled)  # 出力: [2, 4, 6, 8, 10]

# 10倍する関数を作成
multiply_by_10 = partial(multiply, 10)
multiplied = list(map(multiply_by_10, numbers))
print(multiplied)  # 出力: [10, 20, 30, 40, 50]

よくある間違いとその対処法

map結果をlistに変換し忘れ

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

# 間違い:mapオブジェクトそのものを出力
mapped = map(lambda x: x * 2, numbers)
print(mapped)  # 出力: <map object at 0x...>

# 正しい:listに変換
mapped_list = list(map(lambda x: x * 2, numbers))
print(mapped_list)  # 出力: [2, 4, 6, 8, 10]

複数回の反復処理

numbers = [1, 2, 3, 4, 5]
doubled = map(lambda x: x * 2, numbers)

# 1回目の反復
first_iteration = list(doubled)
print(first_iteration)  # 出力: [2, 4, 6, 8, 10]

# 2回目の反復(空になる)
second_iteration = list(doubled)
print(second_iteration)  # 出力: []

# 解決策:必要に応じて再作成
doubled = list(map(lambda x: x * 2, numbers))

イテラブルの長さが異なる場合

list1 = [1, 2, 3, 4, 5]
list2 = [10, 20]  # 短いリスト

# 短い方の長さに合わせられる
result = list(map(lambda x, y: x + y, list1, list2))
print(result)  # 出力: [11, 22](最初の2要素のみ)
print(len(result))  # 出力: 2

# 全要素を処理したい場合はitertools.zip_longest
from itertools import zip_longest
result_full = list(map(lambda x, y: (x or 0) + (y or 0), 
                      *zip_longest(list1, list2, fillvalue=0)))
print(result_full)  # 出力: [11, 22, 3, 4, 5]

map関数を使うべき場面・避けるべき場面

使うべき場面

既存関数の一括適用

strings = ["hello", "world", "python"]
upper_strings = list(map(str.upper, strings))  # 推奨

型変換

string_numbers = ["1", "2", "3", "4", "5"]
integers = list(map(int, string_numbers))  # 推奨

複数リストの要素ごと処理

x = [1, 2, 3]
y = [4, 5, 6]
sums = list(map(lambda a, b: a + b, x, y))  # 推奨

避けるべき場面

シンプルな変換はリスト内包表記

# map使用
doubled = list(map(lambda x: x * 2, numbers))

# リスト内包表記(推奨)
doubled = [x * 2 for x in numbers]

条件付きの変換

# 非効率
positive_doubled = list(map(lambda x: x * 2, filter(lambda x: x > 0, numbers)))

# 効率的
positive_doubled = [x * 2 for x in numbers if x > 0]

副作用を伴う処理

# 避けるべき:mapは変換用、副作用用ではない
list(map(print, numbers))  # printは戻り値がないため非推奨

# 推奨:forループを使用
for num in numbers:
    print(num)

高度なmap関数の応用

並列処理との組み合わせ

from multiprocessing import Pool
import time

def heavy_computation(n):
    # 重い計算のシミュレーション
    time.sleep(0.1)
    return n ** 2

numbers = list(range(10))

# 並列処理でmap実行
if __name__ == "__main__":
    with Pool() as pool:
        results = pool.map(heavy_computation, numbers)
    print(results)

カスタム変換クラス

class DataTransformer:
    def __init__(self, multiplier):
        self.multiplier = multiplier
    
    def transform(self, value):
        return value * self.multiplier
    
    def __call__(self, value):
        return self.transform(value)

transformer = DataTransformer(3)
numbers = [1, 2, 3, 4, 5]

# オブジェクトを関数として使用
transformed = list(map(transformer, numbers))
print(transformed)  # 出力: [3, 6, 9, 12, 15]

まとめ

Pythonのmap関数は、データの一括変換処理を効率的に行うための強力なツールです。重要なポイントをまとめると:

map関数の基本

  • map(function, iterable) の構文
  • 全要素に同じ関数を適用
  • イテレータを返すため、必要に応じてlist()で変換

効果的な使用場面

  • 既存関数の一括適用(str.upper、int、floatなど)
  • 型変換処理
  • 複数リストの要素ごと処理
  • 関数型プログラミングスタイル

実践的な活用方法

  • ファイルパス処理やURL処理
  • データクリーニングと前処理
  • 統計処理での一括計算
  • オブジェクトのメソッド一括呼び出し

ベストプラクティス

  • シンプルな変換はリスト内包表記も検討
  • 大量データではジェネレータとして活用
  • 副作用を伴う処理には使用しない
  • filterやreduceとの組み合わせで強力なパイプライン処理

map関数をマスターすることで、Pythonでのデータ処理がより効率的で関数型プログラミングらしいコードになります。実際のプロジェクトで様々なパターンを試して、適切な使い分けができるようになりましょう。

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座