もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

退屈なことはPythonにやらせようを読んでpython勉強した(パート1 python基礎編)

こんにちは。絶賛風邪ひき中の僕です。

熱があって、気分が悪いので、毎日続いてた運動も今回はやめています。。

早めに治してまたいつものスタイルに持っていきたいです。

ただ、週2回のブログ記事だけは頑張ろうと思っています。

今回は、去年の本なのですが以下の本を読んでます。

pythonは簡単なツールを何個か作るくらいのスキルしか持ち合わあせていません。

ツールづくりも、ググりながらコピりながらやっているので、この際キチンと勉強しようと多い、購入しました。

いつもどおり自分のために、自分が勉強になったなぁと思うところを記録していきます。

事前準備

本ではanacondaをインストールしよう的なことを書いてましたが、pyenv でインストールできるようだったので、落としてみます。

# インストール
$ pyenv install anaconda3-4.3.1
Downloading Anaconda3-4.3.1-MacOSX-x86_64.sh...
-> https://repo.continuum.io/archive/Anaconda3-4.3.1-MacOSX-x86_64.sh
Installing Anaconda3-4.3.1-MacOSX-x86_64...
Installed Anaconda3-4.3.1-MacOSX-x86_64 to /Users/アカウント/.anyenv/envs/pyenv/versions/anaconda3-4.3.1

# globalへセット
$ pyenv global anaconda3-4.3.1

# spyder起動
$ spyder 

起動しました。 かっこいい。。。 pythonの開発環境はこれで行こう。sublime卒業できそうです。

f:id:kojirooooocks:20180210031918p:plain

勉強になったところまとめ

not演算子

否定を表す場合、php!= とは違い、pythonでは not と表現するみたいです。

a = 'abc'
if not a == 'def':
    print('defじゃないよ')
else:
    print('defだよ')
    
>>> defじゃないよ

sys.exit()

phpdie()exit() のようなもので、プログラムを終了させるものです。

個人的には主にデバッグで使えるなと思いました。

ステップ実行出来るIDEあればローカル開発は問題ないでしょうけど、サーバに入って直接デバッグする場面とか来たら、重宝しそうです。

使用するには、 import sysでsysモジュールをimportする必要があります。

None値

phpのnullと同義ということです。

def test():
    print('testだよ')
    
result = test()
print(result == None)

>>> testだよ
>>> True

printのオプション引数(end, sep)

end

通常 print() は渡された文字列の末尾に改行を付けちゃうのですが、それを制御できるのがendオプションです。

print('はじめまして', end='。')
print('よろしく')

>>> はじめまして。よろしく

sep

複数の文字列を引数に渡した時、printが各文字の間に半角スペースを入れるのですが、そレを制御するのが sepオプションです。

print('こんにちは', 'はじめまして', 'よろしくおねがいします', sep='☆')
>>> こんにちは☆はじめまして☆よろしくおねがいします

2つ組み合わせると可愛い文章も作れます。

print('こんにちは', 'はじめまして', 'よろしくおねがいします', sep='♡', end='♡')

>>> こんにちは♡はじめまして♡よろしくおねがいします♡

地味に使えそうですね。

例外処理

try catchのような形で例外処理は書けるようです。

これが一番知りたかったw

import sys
def sum_func(a, b):
    try:
        return a + b
    except TypeError:
        print("引数のどちらかが、数値型ではありません。")
        sys.exit();

result = sum_func(1, 'aa')
print(result)

>>> 引数のどちらかが、数値型ではありません。

phpのexceptionとかとはやはり違いますが、記述方法とかが大幅に違うという訳でもないので、覚えたら問題なく使える感じです。

リスト型

phpの配列のようにどんな型でも入れられますが、配列のkeyの指定は0, 1, 2といった添字になります。

items = ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']
print(items)
print(items[1]);

>>> ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']
>>> のび太くん

リスト型はいろいろおもしろい機能があって、勉強になりました!

負のインデックス

細かいツールを作ってた時に、これがかなり使えるなー!と思ったものでした。

phpでもsubstrとかの引数で負の位置を設定すれば、後ろから判断してるようになりますが、それと同じく、負のkeyの値を入れると、後ろから判断して要素を取り出してくれます。

items = ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']
print(items[-2]);

>>> ドラミちゃん

スライス

keyの指定で : を用いて取得場所の範囲指定して新たなリストとして取得できます。

:を挟んで左側が開始位置、右側は終了位置です。

ただ、終了位置に関しては、以下の通り、indexを指しているようには見えません。

items = ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']
print(items[2:4]);

>> ['しずかちゃん', 'ジャイアン']

# ['しずかちゃん', 'ジャイアン', 'スネ夫']になると思ってた。

どうやら指定した数値のインデックスは含まれないといった感じのようです。

items[ここから:ここ未満] といった感じで覚えたら良さそうです。

スライスでももちろん負のインデックスは使えます

items = ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']
print(items[2:-1]);

>>> ['しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん']

開始位置終了位置ともに省略することも可能です。

開始位置を省略すると、頭から

終了位置を省略すると、最後まで

といった指定になります。

items = ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']

print(items[:3])
print(items[3:])

>>> ['ドラえもん', 'のび太くん', 'しずかちゃん']
>>> ['ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']

便利だ!!

リストの連結と複製

+でリストを連結できて、 *でリストを複製できます。

* は面白かったです。まるでフエルミラー

items1 = ['どら焼き1', 'どら焼き2']
items2 = ['どら焼き3', 'どら焼き4']
items = items1 + items2
print(items)
print(items * 5)

>>> ['どら焼き1', 'どら焼き2', 'どら焼き3', 'どら焼き4']
>>> ['どら焼き1', 'どら焼き2', 'どら焼き3', 'どら焼き4', 'どら焼き1', 'どら焼き2', 'どら焼き3', 'どら焼き4', 'どら焼き1', 'どら焼き2', 'どら焼き3', 'どら焼き4', 'どら焼き1', 'どら焼き2', 'どら焼き3', 'どら焼き4', 'どら焼き1', 'どら焼き2', 'どら焼き3', 'どら焼き4'] 

inとnot in

phpでいうin_array()と似たような感じで、リストの中に指定の要素が入っているか(in)、入っていないか(not in)を調べられます。

items = ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']

# in
print('ドラえもん' in items)
print('ジャイ子' in items)

>>> True
>>> False


# not in
print('美代子さん' not in items)
print('出来杉君' not in items)

>>> True
>>> False

indexメソッド

phparray_search()と似たような動きのようです。

ただ、違うところは、指定の要素がない場合は、Errorになるみたいです。

items = ['ドラえもん', 'のび太くん', 'しずかちゃん', 'ジャイアン', 'スネ夫', 'ドラミちゃん', '出来杉君']

print(items.index('しずかちゃん'))
print(items.index('先生'))

>>> 2
>>> ValueError: '先生' is not in list

insertメソッド

任意の場所に要素を追加できるメソッドです。

これは使えるなーと思いました。

append()もあるようですが、これは他の言語のpushなどと同じように、末尾に要素を追加できるものでした。

items = ['魔界大冒険', 'アニマルプラネット', '海底鬼岩城']
items.insert(1, 'パラレル西遊記')
print(items)

>>> ['魔界大冒険', 'パラレル西遊記', 'アニマルプラネット', '海底鬼岩城']

ちなみに、存在しないインデックスを指定してinsertすると、エラーは出ず、末尾に追加されました。

items = ['魔界大冒険', 'アニマルプラネット', '海底鬼岩城']
items.insert(100, 'パラレル西遊記')
print(items)

>>> ['魔界大冒険', 'アニマルプラネット', '海底鬼岩城', 'パラレル西遊記']

sortメソッド

リストの要素並べ替えのためのメソッドです。

items = [2980, 1980, 5980, 980, 3980]

# 昇順
items.sort()
print(items)

>>> [980, 1980, 2980, 3980, 5980]

# 降順
items.sort(reverse=True)
print(items)

>>> [5980, 3980, 2980, 1980, 980]

sort自体は使用したことがあるのですが、本で紹介されている注意点は知らなかったので、勉強になりました。

sortはASCIIコードでソートするので、文字列のソートでは、大文字が小文字より前に来る。
items = ['d', 'a', 'c', 'b', 'E']
items.sort()
print(items)

>>> ['E', 'a', 'b', 'c', 'd'] 

アルファベット順でソートさせたいときは、オプション引数の key=str.lower を渡すことでアルファベット順でソートしてくれるようです。

items = ['d', 'a', 'c', 'b', 'E']
items.sort(key=str.lower)
print(items)

>>> ['a', 'b', 'c', 'd', 'E']

phpではどうなのだろうと試してみたところ、phpのsort()もASCIIコードでソートしているようでした。

無知なダメ男ですいません。。。

<?php
$test = ['d', 'a', 'c', 'b', 'E'];
sort($test);
echo var_export($test, true);

>>> $ php test.php 
array (
  0 => 'E',
  1 => 'a',
  2 => 'b',
  3 => 'c',
  4 => 'd',

phpで、pythonsort(key=str.lower)と同じ動きするのはどれかな?と調べたところ natcasesort というのがそれに当たるようです。

<?php
$test = ['d', 'a', 'c', 'b', 'E'];
natcasesort($test);
echo var_export($test, true);

>>> $ php test.php 
array (
  1 => 'a',
  3 => 'b',
  2 => 'c',
  0 => 'd',
  4 => 'E',

pythonの勉強しながらphpの勉強もできて、一挙両得でした。

タプル型

リストとよく似た感じですが、以下2つが違います。

  1. []ではなく()で要素を定義する。
  2. イミュータブル(変更ができないもの)である。
items = ('ルパン', '次元', '五右衛門')
print(items)

>>> ('ルパン', '次元', '五右衛門')

変更しないものかどうかというので、リストと使い分ける感じでしょうか。

ただ、調べると絶対変更できないというわけではないようで、スライスや連結を使えば追加、削除などは行えるようです。

# 追加(不二子、銭形を追加したい)
items1 = ('ルパン', '次元', '五右衛門')
items2 = ('不二子', '銭形')
items  = items1 + items2
print(items)

>>> ('ルパン', '次元', '五右衛門', '不二子', '銭形')

# 削除(不二子を消したい)
items1 = ('ルパン', '次元', '五右衛門', '不二子', '銭形')
items  = items1[0:3] + items1[-1:]
print(items)

>>> ('ルパン', '次元', '五右衛門', '銭形')

また、要素が一つのタプル型を作る際は、以下のように,を末尾につける必要があるようです。

つけないと、エラーは出ませんが、以下の例だと文字列型とみなされるようです。

items = ('ルパン', )
print(items)

>>> ('ルパン',)

items = ('ルパン')
print(items)

>>> ルパン

リストの参照渡し

リスト型を格納する変数を、別変数に代入した際は、phpでいう値渡しではなく参照渡しになるようです。

items = ['コナン', '平次', '蘭']
copy_items = items
copy_items.append('阿笠博士')
print(items)
print(copy_items)

>>> ['コナン', '平次', '蘭', '阿笠博士']
>>> ['コナン', '平次', '蘭', '阿笠博士']

面白い動きしますよね。

では値渡しなリストを作るにはどうしたらよいか調べるとcopyモジュールのcopyを使えばよいとのことでした。

import copy
items = ['コナン', '平次', '蘭']
copy_items = copy.copy(items)
copy_items.append('阿笠博士')
print(items)
print(copy_items)

>>> ['コナン', '平次', '蘭']
>>> ['コナン', '平次', '蘭', '阿笠博士']

ただ、以下のように入れ子のリストになっているような場合は、copyを使用しても参照渡しになってしまいます。

import copy
items = [['新一', '蘭', '平次'], ['コナン', '源太', '光彦', '歩美']]
copy_items = copy.copy(items)
copy_items[1].append('阿笠博士')
print(items)
print(copy_items)

>>> [['新一', '蘭', '平次'], ['コナン', '源太', '光彦', '歩美', '阿笠博士']]
>>> [['新一', '蘭', '平次'], ['コナン', '源太', '光彦', '歩美', '阿笠博士']]

これを解決するのが、 copyモジュールのdeepcopy() です。

import copy
items = [['新一', '蘭', '平次'], ['コナン', '源太', '光彦', '歩美']]
copy_items = copy.deepcopy(items)
copy_items[1].append('阿笠博士')
print(items)
print(copy_items)

>>> [['新一', '蘭', '平次'], ['コナン', '源太', '光彦', '歩美']]
>>> [['新一', '蘭', '平次'], ['コナン', '源太', '光彦', '歩美', '阿笠博士']]

なんでそうなるのだろうと色々調べてみてると、コチラの記事に詳しく書かれておりました。

勉強になりました。

辞書型

php連想配列的な使い方ができます。

items = {'name': 'ドラえもん', 'size': '100cm', 'type': '猫型ロボット'}
print(items)
print(items['name'])

>>> {'name': 'ドラえもん', 'size': '100cm', 'type': '猫型ロボット'}
>>> ドラえもん

辞書型には順番の概念がないので、以下の2つはTrueとなります。

item1 = {'name': 'ドラえもん', 'size': '100cm', 'type': '猫型ロボット'}
item2 = {'size': '100cm', 'type': '猫型ロボット', 'name': 'ドラえもん'}
print(item1 == item2)

>>> True

keys(), vaules(), items()

脳内変換できちゃいますが、keysはkeyの一覧、 valuesは値の一覧、itemsはkey, valueのセットを取得できます。

items = {'name': 'ドラえもん', 'size': '100cm', 'type': '猫型ロボット'}
print(items.keys())
print(items.values())
print(items.items())

>>> dict_keys(['name', 'size', 'type'])
>>> dict_values(['ドラえもん', '100cm', '猫型ロボット'])
>>> dict_items([('name', 'ドラえもん'), ('size', '100cm'), ('type', '猫型ロボット')])

setdefault()

指定のキーが辞書に登録されていない場合のみ指定の値を保存できるというメソッドです。

すでにセットされている場合は、上書きするのではなく、すでにセットされている値を返してくれます。

このメソッドは地味に便利だなーと思いました。

items = {'name': 'ドラえもん', 'size': '100cm', 'type': '猫型ロボット'}
items.setdefault('gender', '男?')
print(items)
print(items.setdefault('type', '狸ロボット'))
print(items)

>>> {'name': 'ドラえもん', 'size': '100cm', 'type': '猫型ロボット', 'gender': '男?'}
>>> 猫型ロボット
>>> {'name': 'ドラえもん', 'size': '100cm', 'type': '猫型ロボット', 'gender': '男?'}

便利な文字列メソッド

文字列でも結構いいメソッドが揃ってました。

新しい言語はおもしろいなー

upper(), lower(), isupper(), islower()

upper()は全ての文字を大文字に、lower()は全ての文字を小文字にします。

isupper()は文字列全てが大文字かどうか、islower()は文字列全てが小文字かどうかを調べます。

print("abcde".upper())
print("ABCDE".lower())
print("abcde".islower())
print("ABcde".islower())
print("abCDE".isupper())
print("ABCDE".isupper())

>>> ABCDE
>>> abcde
>>> True
>>> False
>>> False
>>> True

isalpha(), isalnum(), isdecimal(), isspace(), istitle()

  • isalpha()は、英文字のみで構成されているかどうかを調べます。
  • isalnum()は、英文字か数字から構成されているかどうかを調べます。
  • isdecimal()は、数字のみで構成されているかどうかを調べます。
  • isspace()は、スペースかタブか改行だけで構成されているかどうかを調べます。
  • istitle()は、先頭が大文字でそれ以降が小文字の英単語から構成されているかどうかを調べます。

istitle()おもしろいですね。

print('abcde'.isalpha())
print('abcde1'.isalpha())
print('abcde'.isalnum())
print('abcde'.isdecimal())
print('12345'.isdecimal())
print('abcde'.isspace())
print('     '.isspace())
print('This Is A Pen'.istitle())
print('This Is a Pen'.istitle())

>>> True
>>> False
>>> True
>>> False
>>> True
>>> False
>>> True
>>> True
>>> False

startswith(), endswith()

  • startswith()は、指定の文字列から始まっているかどうかを調べます。
  • endswith()は、指定の文字列で終わっているかどうかを調べます。
print('abcdefg'.startswith('ab'))
print('abcdefg'.startswith('bc'))
print('abcdefg'.endswith('fg'))
print('abcdefg'.endswith('de'))

>>> True
>>> False
>>> True
>>> False

rjust(), ljust(), center()

文字列を右揃え、左揃え、中央揃えしてくれます。

print('kojirock'.rjust(30, " "))
print('kojirock'.rjust(30, "="))
print('kojirock'.ljust(30, " "))
print('kojirock'.ljust(30, "="))
print('kojirock'.center(30, " "))
print('kojirock'.center(30, "="))

>>>                       kojirock
>>> ======================kojirock
>>> kojirock                      
>>> kojirock======================
>>>            kojirock           
>>> ===========kojirock===========

おもしろいメソッドでした。

 終わりに

いろいろおもしろい物ありました。

結構なボリュームになったな。。。

今回はこの本で紹介されていたpythonの基礎部分の勉強でしたが、次回は紹介されている応用編を、記事にしたいと思います。

ではでは。