Python 1行で複数の変数に値を代入する方法 – 多重代入とアンパック完全ガイド
![]() |
20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード |
| |
週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ |
| |
10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks |
目次
多重代入とは?
Python では1行で複数の変数に値を代入する「多重代入(Multiple Assignment)」や「アンパック(Unpacking)」と呼ばれる機能があります。この機能により、コードをより簡潔で読みやすく書くことができ、効率的なプログラミングが可能になります。
基本的な多重代入
1. 基本的な構文
# 基本的な多重代入
a, b, c = 1, 2, 3
print(f"a={a}, b={b}, c={c}") # a=1, b=2, c=3
# 同じ値を複数の変数に代入
x = y = z = 10
print(f"x={x}, y={y}, z={z}") # x=10, y=10, z=10
# 文字列での例
name, age, city = "太郎", 25, "東京"
print(f"{name}さん({age}歳)は{city}在住")
2. リストからの代入
# リストから変数へ代入
numbers = [1, 2, 3]
a, b, c = numbers
print(f"a={a}, b={b}, c={c}") # a=1, b=2, c=3
# ネストしたリスト
data = [["太郎", 25], ["花子", 30]]
person1, person2 = data
name1, age1 = person1
name2, age2 = person2
print(f"{name1}: {age1}歳, {name2}: {age2}歳")
3. タプルからの代入
# タプルから変数へ代入
coordinates = (10, 20)
x, y = coordinates
print(f"座標: ({x}, {y})")
# 関数の戻り値(タプル)を受け取る
def get_user_info():
return "太郎", 25, "エンジニア"
name, age, job = get_user_info()
print(f"{name}({age}歳)- {job}")
変数の値の交換
1. 簡単な値の交換
# 従来の方法(一時変数が必要)
a, b = 10, 20
temp = a
a = b
b = temp
print(f"a={a}, b={b}") # a=20, b=10
# Pythonの多重代入(推奨)
a, b = 10, 20
a, b = b, a
print(f"a={a}, b={b}") # a=20, b=10
2. 複数変数の交換
# 3つの変数の循環
x, y, z = 1, 2, 3
x, y, z = y, z, x
print(f"x={x}, y={y}, z={z}") # x=2, y=3, z=1
# リスト要素の交換
numbers = [1, 2, 3, 4, 5]
numbers[0], numbers[4] = numbers[4], numbers[0]
print(numbers) # [5, 2, 3, 4, 1]
アスタリスク(*)を使った展開
1. 基本的なアスタリスク展開
# 最初と最後を取得、残りはリストで受け取る
numbers = [1, 2, 3, 4, 5]
first, *middle, last = numbers
print(f"最初: {first}") # 最初: 1
print(f"中間: {middle}") # 中間: [2, 3, 4]
print(f"最後: {last}") # 最後: 5
# 最初の要素と残り
head, *tail = [1, 2, 3, 4]
print(f"先頭: {head}") # 先頭: 1
print(f"残り: {tail}") # 残り: [2, 3, 4]
2. 文字列での展開
# 文字列の分解
word = "Python"
first, *middle, last = word
print(f"最初: {first}") # 最初: P
print(f"中間: {middle}") # 中間: ['y', 't', 'h', 'o']
print(f"最後: {last}") # 最後: n
# CSVデータの処理
csv_line = "太郎,25,東京,エンジニア,Python"
name, age, *details = csv_line.split(',')
print(f"名前: {name}, 年齢: {age}")
print(f"詳細: {details}")
辞書のアンパック
1. 辞書の展開
# 辞書から複数の値を取得
user_data = {"name": "太郎", "age": 25, "city": "東京"}
# 従来の方法
name = user_data["name"]
age = user_data["age"]
city = user_data["city"]
# items()を使った方法
for key, value in user_data.items():
print(f"{key}: {value}")
# 辞書のキーと値を分離
keys, values = zip(*user_data.items())
print(f"キー: {list(keys)}")
print(f"値: {list(values)}")
2. **を使った辞書展開
def greet(name, age, city):
return f"{name}さん({age}歳)は{city}在住です"
user_info = {"name": "花子", "age": 30, "city": "大阪"}
# 辞書を引数として展開
message = greet(**user_info)
print(message) # 花子さん(30歳)は大阪在住です
# 複数の辞書をマージ
dict1 = {"a": 1, "b": 2}
dict2 = {"c": 3, "d": 4}
merged = {**dict1, **dict2}
print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
実践的な使用例
1. ファイル処理での活用
def parse_log_line(line):
parts = line.strip().split()
if len(parts) >= 4:
timestamp, level, module, *message = parts
return {
"timestamp": timestamp,
"level": level,
"module": module,
"message": " ".join(message)
}
return None
# 使用例
log_line = "2024-01-15 ERROR database Connection failed"
parsed = parse_log_line(log_line)
if parsed:
print(f"時刻: {parsed['timestamp']}")
print(f"レベル: {parsed['level']}")
2. 座標計算での活用
def calculate_distance(point1, point2):
x1, y1 = point1
x2, y2 = point2
return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
def get_rectangle_info(rect):
x, y, width, height = rect
return {
"area": width * height,
"perimeter": 2 * (width + height),
"center": (x + width/2, y + height/2)
}
# 使用例
p1, p2 = (0, 0), (3, 4)
distance = calculate_distance(p1, p2)
print(f"距離: {distance}")
rectangle = (10, 20, 50, 30)
info = get_rectangle_info(rectangle)
print(f"面積: {info['area']}")
3. データ分析での活用
def analyze_scores(scores):
if not scores:
return None
sorted_scores = sorted(scores)
min_score, *middle, max_score = sorted_scores
return {
"min": min_score,
"max": max_score,
"count": len(scores),
"average": sum(scores) / len(scores)
}
# CSVデータの処理
def process_csv_row(row):
student_id, name, *subject_scores = row.split(',')
scores = [int(score) for score in subject_scores]
return {
"id": student_id,
"name": name,
"scores": scores,
"total": sum(scores)
}
# 使用例
test_scores = [85, 92, 78, 96, 88]
analysis = analyze_scores(test_scores)
print(f"最低点: {analysis['min']}, 最高点: {analysis['max']}")
enumerate()とzip()での活用
1. enumerate()との組み合わせ
# リストのインデックスと値を同時に取得
fruits = ["りんご", "バナナ", "オレンジ"]
for index, fruit in enumerate(fruits):
print(f"{index + 1}. {fruit}")
# 辞書作成
fruit_dict = {i: fruit for i, fruit in enumerate(fruits)}
print(fruit_dict) # {0: 'りんご', 1: 'バナナ', 2: 'オレンジ'}
2. zip()との組み合わせ
# 複数のリストを同時に処理
names = ["太郎", "花子", "次郎"]
ages = [25, 30, 35]
cities = ["東京", "大阪", "名古屋"]
for name, age, city in zip(names, ages, cities):
print(f"{name}({age}歳)- {city}")
# 辞書の作成
user_dict = {name: {"age": age, "city": city}
for name, age, city in zip(names, ages, cities)}
print(user_dict)
関数での多重代入
1. 複数の戻り値を返す関数
def get_statistics(numbers):
if not numbers:
return 0, 0, 0, 0
total = sum(numbers)
count = len(numbers)
avg = total / count
max_val = max(numbers)
return total, count, avg, max_val
def divide_with_remainder(dividend, divisor):
quotient = dividend // divisor
remainder = dividend % divisor
return quotient, remainder
# 使用例
data = [10, 20, 30, 40, 50]
total, count, average, maximum = get_statistics(data)
print(f"合計: {total}, 平均: {average:.2f}")
result, remainder = divide_with_remainder(17, 5)
print(f"17 ÷ 5 = {result} 余り {remainder}")
2. ネストした構造の処理
def process_nested_data(data):
results = []
for item in data:
if isinstance(item, (list, tuple)) and len(item) >= 2:
key, value, *extra = item
results.append({
"key": key,
"value": value,
"extra": extra
})
return results
# 使用例
nested_data = [
("name", "太郎", "追加情報1"),
("age", 25),
("city", "東京", "区", "町")
]
processed = process_nested_data(nested_data)
for item in processed:
print(f"{item['key']}: {item['value']}")
if item['extra']:
print(f" 追加: {item['extra']}")
パフォーマンスの考慮事項
1. 効率的な値の交換
import timeit
# 多重代入による交換(高速)
def swap_multiple():
a, b = 10, 20
a, b = b, a
return a, b
# 一時変数による交換(相対的に低速)
def swap_temp():
a, b = 10, 20
temp = a
a = b
b = temp
return a, b
# パフォーマンス比較
time1 = timeit.timeit(swap_multiple, number=1000000)
time2 = timeit.timeit(swap_temp, number=1000000)
print(f"多重代入: {time1:.6f}秒")
print(f"一時変数: {time2:.6f}秒")
2. 大量データでの注意点
# 大量データでのアンパック
def process_large_data():
# 効率的:必要な部分のみ取得
large_list = list(range(1000000))
first, second, *_ = large_list # 残りは無視
return first + second
# 非効率:すべてをアンパック
def inefficient_process():
large_list = list(range(1000000))
# これは避けるべき(メモリを大量消費)
*all_items, = large_list
return sum(all_items[:2])
print(process_large_data()) # 効率的な方法
よくある間違いと対処法
1. 要素数の不一致
# エラーになる例
try:
a, b, c = [1, 2] # ValueError: not enough values to unpack
except ValueError as e:
print(f"エラー: {e}")
# 安全な方法
def safe_unpack(data, expected_count):
if len(data) == expected_count:
return data
elif len(data) < expected_count:
# 不足分をNoneで埋める
return data + [None] * (expected_count - len(data))
else:
# 余分な要素は切り捨て
return data[:expected_count]
# 使用例
data = [1, 2]
a, b, c = safe_unpack(data, 3)
print(f"a={a}, b={b}, c={c}") # a=1, b=2, c=None
2. 可変オブジェクトの共有
# 危険な例:すべての変数が同じリストを参照
a = b = c = []
a.append(1)
print(f"a={a}, b={b}, c={c}") # すべて [1] になる
# 正しい方法:それぞれ独立したリスト
a, b, c = [], [], []
a.append(1)
print(f"a={a}, b={b}, c={c}") # a=[1], b=[], c=[]
# または
def create_empty_lists(count):
return [[] for _ in range(count)]
a, b, c = create_empty_lists(3)
3. ネストしたアンパックの注意点
# 複雑なネスト構造
data = [["太郎", [25, "東京"]], ["花子", [30, "大阪"]]]
# 段階的にアンパック(推奨)
for person_data in data:
name, details = person_data
age, city = details
print(f"{name}: {age}歳, {city}")
# 一度にアンパック(複雑になりがち)
# (name1, (age1, city1)), (name2, (age2, city2)) = data
応用テクニック
1. 条件付きアンパック
def conditional_unpack(data):
if len(data) == 2:
x, y = data
return f"2D座標: ({x}, {y})"
elif len(data) == 3:
x, y, z = data
return f"3D座標: ({x}, {y}, {z})"
else:
return "不正な座標データ"
# 使用例
print(conditional_unpack([1, 2])) # 2D座標: (1, 2)
print(conditional_unpack([1, 2, 3])) # 3D座標: (1, 2, 3)
2. 動的な変数生成
# 辞書を使った動的変数管理
def create_variables_dict(names, values):
return dict(zip(names, values))
# 使用例
var_names = ["x", "y", "z"]
var_values = [10, 20, 30]
variables = create_variables_dict(var_names, var_values)
print(variables) # {'x': 10, 'y': 20, 'z': 30}
# 一括での値設定
def set_multiple_attributes(obj, **kwargs):
for key, value in kwargs.items():
setattr(obj, key, value)
class Point:
pass
point = Point()
set_multiple_attributes(point, x=10, y=20, z=30)
print(f"座標: ({point.x}, {point.y}, {point.z})")
まとめ
Python の多重代入とアンパックを効果的に使うポイント:
推奨される使用場面
- 値の交換:
a, b = b, aで簡潔に - 関数の戻り値: 複数の値を一度に受け取る
- リスト/タプルの分解: 構造化データの処理
- 座標データ:
x, y = pointのような自然な表現
注意すべき点
- 要素数の一致: アンパック時の要素数に注意
- 可変オブジェクト:
a = b = []のような共有を避ける - パフォーマンス: 大量データでのアンパックは慎重に
- 可読性: 複雑すぎるネストは避ける
多重代入を適切に活用することで、よりPythonicで効率的なコードが書けるようになります。
■「らくらくPython塾」が切り開く「呪文コーディング」とは?
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座
![]() |
20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード |
| |
週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ |
| |
10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks |




