スポンサーリンク

Python初心者が勘違いしやすい「便利そうで危険な書き方」5選

Python入門

はじめに

Pythonを学び始めたばかりの頃って、「ちゃんと動いた!」だけで嬉しくなりますよね。 サンプルコードをコピペして実行し、エラーが出なければ「これで正解なんだ」と思ってしまうのも、すごく自然なことです。

でも実は、Python初心者が「便利そう」「かっこいい」と感じて真似しがちな書き方の中には、後から自分や他人を確実に苦しめる“危険なコード”が混ざっています。

そのコードは、たしかに今は動くかもしれません。 けれど少し時間が経ったあとに見返すと、

  • 何をしているのか分からない
  • どこを直せばいいのか分からない
  • 触るのが怖くて放置する

――そんな「読めないコード」になってしまうことが本当によくあります。

Pythonはもともと、「読みやすさ」をとても大切にする言語です。 短く書けることや、賢そうに見えることよりも、「あとから読んで理解できるか」が重視されています。

この記事では、Python初心者が特につまずきやすい

  • 一見便利そうに見えるけど危険な書き方
  • なぜそれが問題になるのか
  • どう書き直せば安全なのか

を、具体例と一緒に解説していきます。

「今はまだ一人で書いているから大丈夫」と思っている方ほど、ぜひ読んでみてください。 早い段階で“避けるべき書き方”を知っておくことが、あとあと大きな差になります。




結論

結論からお伝えします。 Pythonで本当に大事なのは、「動くコード」よりも「後から読めるコード」です。

初心者のうちは、

  • 短く書ける
  • 1行で済む
  • なんとなく賢そう

こうした要素に惹かれてコードを書きがちですが、これがそのまま積み重なると、あとで必ず困るコードになります。

今回紹介する「便利そうで危険な書き方」は、どれも

  • 初心者が悪気なくやってしまう
  • その場では問題が起きにくい
  • でも後から修正・理解が難しくなる

という共通点があります。

逆に言えば、これから解説する5つのポイントを意識するだけで、

  • 自分で読み返せるコード
  • 人に見せても恥ずかしくないコード
  • 安心して修正できるコード

に一気に近づきます。

難しいテクニックや高度な設計は、まだ必要ありません。 まずは「やらないほうがいい書き方」を知ることが、Python上達への一番の近道です。




Python初心者が勘違いしやすい「危険な書き方」5選

複雑すぎるワンライナー(内包表記・lambdaの乱用)

Pythonを学び始めると、リスト内包表記や lambda を使った短い書き方に出会います。 最初は「こんなにスッキリ書けるんだ!」と感動しますよね。

たとえば、こんなコードです。


result = [x for x in data if x % 2 == 0 if x > 10]

このくらいなら、まだ読める人も多いと思います。 でも初心者がやりがちなのは、ここからさらに条件や処理を足してしまうことです。


result = [func(x) for x in data if x % 2 == 0 and x > 10 and check(x)]

こうなると、「この1行は何をしているのか」を理解するために、頭の中でかなりの処理を同時に追う必要があります。

問題は、短いこと自体ではありません。 1行に情報を詰め込みすぎると、読む側の負担(メンタルロード)が一気に跳ね上がります。

特に初心者のうちは、

  • 条件が2つ以上ある
  • 関数呼び出しが混ざる
  • 処理の意図を説明できない

このどれかに当てはまった時点で、ワンライナーは危険信号です。

では、どう書けばいいのでしょうか。 こういう場合は、素直に処理を分けたほうが安全です。


result = []
for x in data:
    if x % 2 != 0:
        continue
    if x <= 10:
        continue
    if not check(x):
        continue
    result.append(func(x))

行数は増えましたが、「何をしているか」は一目で分かりますよね。 あとから条件を追加したり、デバッグしたりするのもずっと楽になります。

Pythonらしい書き方とは、「短いコード」ではなく「意図が伝わるコード」です。 ワンライナーは、読める自信がついてから使うくらいがちょうどいい、と私は思っています。




ミュータブルなデフォルト引数(list = [])

これは、Python初心者がほぼ確実に一度は踏む罠です。 しかもエラーが出ないので、「何が悪いのか分からないまま」進んでしまいがちです。

たとえば、こんな関数を書いたことはありませんか?


def add_item(item, items=[]):
    items.append(item)
    return items

一見すると問題なさそうに見えますよね。 実際、1回目の呼び出しでは普通に動きます。


print(add_item(1))  # [1]
print(add_item(2))  # [1, 2]

「え?なんで前の結果が残ってるの?」 ここで初めて違和感に気づく人がとても多いです。

これは、Pythonではデフォルト引数が関数定義時に一度だけ作られるという仕様が原因です。 リストのような変更可能(ミュータブル)なオブジェクトを使うと、呼び出し間で状態が共有されてしまいます。

この挙動の背景には、「ミュータブル(変更可能)」と「イミュータブル(変更不可)」という考え方があります。 ここが曖昧なままだと、同じミスを何度も繰り返してしまいます。

では、安全な書き方はどうなるでしょうか。


def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

このように None を使うのが、Pythonでは定番の回避パターンです。 少し回りくどく見えるかもしれませんが、意図しないバグを確実に防げる書き方です。

初心者のうちは、「動いたからOK」ではなく、 「この関数は毎回まっさらな状態で始まるか?」を意識するだけで、コードの安全性が一気に上がります。




組み込み関数名と同じ変数名を使う(sum / str / id)

Python初心者がやりがちなミスの中でも、 「意味的には正しそうだから気づきにくい」のがこのパターンです。

たとえば、合計値を表したいときに、こんなコードを書いてしまうことがあります。


sum = 0
for x in data:
    sum += x

一見すると何も問題なさそうですよね。 でも、この時点で Python の組み込み関数 sum() を上書きしてしまっています。

その結果、あとでこんなコードを書くと……


total = sum(data)

エラーが発生します。 「え、さっきまで普通に使えてたのに?」と混乱する原因になります。

これは sum だけでなく、

  • str
  • list
  • id
  • dict

など、多くの組み込み名で起こりえます。

初心者のうちは、

  • エラーメッセージが分かりづらい
  • どこで壊したのか追いにくい

という理由から、デバッグにかなり時間を取られてしまいます。

こうしたトラブルを防ぐためには、少し具体的な名前を付けるのがコツです。


total_sum = 0
user_id = 123
text_str = "hello"

「短い名前=良い名前」ではありません。 役割が一瞬で分かるかどうかが、変数名のいちばん大事なポイントです。

変数名の付け方については、初心者がつまずきやすいポイントをまとめた記事があります。

最初のうちは少し長く感じるかもしれませんが、 あとから読み返したときの理解スピードは、確実にこちらのほうが速くなります。




if文の深すぎるネスト(ifピラミッド)

条件分岐を書いているうちに、if文がどんどん右にずれていく── そんな経験はありませんか?

たとえば、こんなコードです。


if user is not None:
    if user.is_active:
        if user.age >= 18:
            if user.has_permission:
                do_something()

動作自体は問題ありません。 でも、このコードを上から一気に理解するのはかなり大変です。

ネストが深くなると、

  • どの条件で処理が実行されるのか分かりにくい
  • 途中で条件を追加・変更しづらい
  • インデントを見るだけで疲れる

といった問題が出てきます。

こういう場合におすすめなのが、ガード節(早めにreturnする書き方)です。


if user is None:
    return
if not user.is_active:
    return
if user.age < 18:
    return
if not user.has_permission:
    return

do_something()

条件は同じでも、「どの条件で弾かれるのか」が一目で分かりますよね。 処理の本体も、下のほうにスッと現れるので読みやすくなります。

if文のネストが深くなり始めたら、

  • returnで早く抜けられないか?
  • 条件を関数に切り出せないか?

この2点を考えるクセを付けるだけで、コードはかなり整理されます。


グローバル変数の安易な使用

「関数に渡すのが面倒だから」「どこからでも使えると楽だから」 そんな理由でグローバル変数を使ってしまうのも、初心者がハマりやすいポイントです。


count = 0

def increment():
    global count
    count += 1

このコードの問題は、countがどこで変更されるのか追いづらいことです。 処理が増えてくると、「いつ」「誰が」値を変えたのか分からなくなります。

グローバル変数は、コードに副作用を生みやすくします。 副作用が増えるほど、バグの原因は見えなくなっていきます。

副作用という考え方については、次の記事で詳しく解説しています。

基本的には、

  • 必要な値は引数で渡す
  • 結果は戻り値で受け取る

という形を守るだけで、コードの見通しは一気に良くなります。


def increment(count):
    return count + 1

少し手間に感じるかもしれませんが、 「値の流れが追えるコード」は、それだけで信頼性が高くなります。




「悪い書き方」を避けるための実践チェックリスト

ここまで読んで、「なるほど、これは確かに危ないかも」と感じた方も多いと思います。 でも実際にコードを書く場面では、毎回この記事を思い出すのは大変ですよね。

そこでこの章では、自分のコードをその場でチェックできる実践用リストを用意しました。 書き終えたあとに、軽く見直すだけでも効果があります。

  • この1行、声に出して説明できる?
    もし途中で詰まるなら、情報を詰め込みすぎている可能性があります。
  • 条件や処理が増えたらすぐ壊れそうじゃない?
    少しの変更で全体を触る必要があるコードは、将来の地雷です。
  • 半年後の自分が初見で読める?
    「自分なら分かる」は意外と信用できません。
  • 変数名だけで役割が伝わる?
    コメントがないと分からない名前は、改善の余地ありです。
  • 値はどこから来て、どこへ行くか追える?
    グローバル変数や副作用が多いと、ここが一気に崩れます。

このチェックにいくつも引っかかる場合、 「まだ早い書き方」を無理に使っている可能性が高いです。

Pythonでは、分かりやすく書くこと自体が正解です。 遠回りに見えても、結果的には一番早く上達します。


学習段階で「正しい書き方」を身につけるには

ここまでで、「これは避けたほうがいいな」という書き方はかなり見えてきたと思います。 ただ、NG例を知るだけでは、「じゃあ普段どう書けばいいの?」という疑問が残りますよね。

初心者の方を見ていると、

  • ダメな理由は分かったけど、正解が分からない
  • ネットのコードが全部良さそうに見える
  • 結局、感覚で書いてしまう

という状態に陥りがちです。

この段階で一番大切なのは、「ちゃんとしたコード」を大量に見ることです。 自己流を続けるより、基準となる書き方を先に体に入れてしまったほうが、あとが楽になります。

そのための選択肢として、初心者〜初級者に特に相性がいいのが、次のような教科書系の書籍です。

実践力を身につける Pythonの教科書 第2版
✅ Amazonでチェックする✅ 楽天でチェックする

このタイプの本は、

  • 変な省略をしない
  • 読みやすさを前提に書かれている
  • 「なぜそう書くのか」が説明されている

という点で、コードの基準作りにとても向いています。

また、「実務っぽいコードを早めに触りたい」という人には、こちらもおすすめです。

シゴトがはかどる Python自動処理の教科書
✅ Amazonでチェックする✅ 楽天でチェックする

実用寄りのコードは、

  • 読みづらいとすぐ破綻する
  • 後から修正される前提で書かれている

ため、自然と「危険な書き方」が避けられています。

最初からPythonicを完璧に目指す必要はありません。 まずは「変な癖がつかない環境」を用意することが、長く見て一番の近道です。




よくある誤解・注意点

ここまで読んで、「じゃあ短いコードや賢そうな書き方は全部ダメなの?」と感じた方もいるかもしれません。 ですが、いくつか誤解されやすいポイントがあるので、ここで整理しておきます。

短いコード=良いコード、ではない

Pythonでは短く書ける構文が多いですが、 短さはゴールではなく結果です。

読みやすさ・変更しやすさを優先した結果として短くなるのはOKですが、 「短くしたいから1行に詰め込む」のは本末転倒です。

上級者のコードをそのまま真似しなくていい

ネットや書籍で見かけるコードの中には、

  • 前提知識が共有されている
  • 文脈を省略している
  • チーム内ルールがある

といったケースも多くあります。

初心者が同じ書き方をすると、 「意味は分からないけど動くコード」になりがちです。

最初のうちは、自分が説明できる書き方だけを採用するくらいでちょうどいいです。

Pythonicは「慣れてから」で大丈夫

Pythonicという言葉を意識しすぎて、 かえってコードが読みにくくなる人も少なくありません。

まずは、

  • 処理の流れが追える
  • 条件や意図が分かる
  • 安心して修正できる

この3点を満たすことを優先してください。

Pythonicな書き方は、基礎が固まったあとに自然と身についてきます




まとめ

今回は、Python初心者が「便利そう」「かっこいい」と感じて真似しがちな、 実は危険な書き方を5つ紹介しました。

  • 複雑すぎるワンライナー
  • ミュータブルなデフォルト引数
  • 組み込み関数名と同じ変数名
  • 深すぎるif文のネスト
  • 安易なグローバル変数の使用

どれも「今すぐエラーになる」わけではありません。 だからこそ、初心者のうちは気づきにくく、あとから自分を苦しめる原因になります。

大切なのは、 Pythonが得意なことは「賢く書くこと」ではなく「分かりやすく書くこと」だと理解することです。

最初のうちは、

  • 行数が増えても気にしない
  • 自分で説明できる書き方を選ぶ
  • あとから直しやすい形を意識する

これだけで、コードの質は確実に変わります。

「動いたからOK」から一歩進んで、 「安心して読み返せるコード」を目指していきましょう。


参考文献


よくある質問(Q&A)

Q
ワンライナーは全部使わないほうがいいですか?
A

いいえ、全部が悪いわけではありません。 一目で処理内容が分かる範囲であれば、ワンライナーはとても便利です。

ただし、「説明できない」「条件が増えそう」と感じたら、 その時点で分けて書いたほうが安全です。

Q
Pythonicな書き方は、いつから意識すればいいですか?
A

基本的な構文に慣れて、 「自分のコードを読み返す余裕が出てきた頃」で十分です。

最初からPythonicを目指すより、 読みやすさを優先したほうが結果的に近道になります。

Q
可読性って、人によって感じ方が違いませんか?
A

多少の主観はありますが、

  • 処理の流れが追える
  • 名前から役割が分かる
  • 副作用が少ない

といった点は、多くの人に共通する基準です。

「他人が読む前提」で書く意識を持つだけで、 可読性は大きく改善します。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク