40のおっさんのPython学習記録

20年以上前、学部の必修のC言語が全く理解できずに同級生に放り投げ、その後コーディングから遠ざかったガチ文系のおっさんが、ふと思い立ってPythonに挑戦しています。

新たな気づき(Chapter 6-3、6-4)

  • list_a.sort()はリストを書き換えてしまうが、list_b=sorted(list_a)は新たなリストを作る。
  • list_a.sort(reverse=True)、list_b=sorted(list_a,reverse=True)で降順にする。
  • リストの中の並びを単に逆にしたい場合はlist_a.reverse()(これExcelにはない)
  • list_a.sort(key=len)のように関数をキーにして文字の大きさ順にソートすることもできる。
  • list_a.sort(key=str.lower)で文字列のリストの中身を小文字にした上でソートできる。しないと大文字が先に来る。
  • 以下のようにすると、番号付きリストにできる。iとwhoを入れ替えてもかまわない。いずれにせよ最初の変数が数字、次の変数がリストから取り出した名前。(names,1)の1を置くことでカウンターの開始数値を1にできる。
names=["埋木","梅本","呻き","梅なんとか"]
for i, who in enumerate(names,1):
    print(i,who+"さん")
1 埋木さん
2 梅本さん
3 呻きさん
4 梅なんとかさん
  • zip関数を使うことで2つのリストをまとめてまわすことができる。
family=["埋木","梅本","呻き","梅なんとか"]
first=["幽閉","横柄","遊兵","幽霊"]
fullname=[]
for n1, n2 in zip(family,first):
    fullname.append(f"{n1} {n2}")
print(fullname)
  • リスト内包表記を使うことで上のコードは以下の様に書き換えられる。
family=["埋木","梅本","呻き","梅なんとか"]
first=["幽閉","横柄","遊兵","幽霊"]
fullname=[f"{n1} {n2}" for n1, n2 in zip(family, first)]
print(fullname)
  • リスト内包表記には条件式を含むこともできるし、複数の条件式でもいい。全ての条件式を満たすものが残る。
numbers=[2.1,9,"梅岡",8.0,"阪急梅田",1.6]
only_numbers = [num for num in numbers if isinstance(num,(int, float)) if num>5]
print(only_numbers)
  • data=[[1,2,3,4],[5,6,7],[8,9]]に対して以下のようにfor inを並べて書くと、
data=[[1,2,3,4],[5,6,7],[8,9]]
result1=[num*2 for alist in data for num in alist]
print(result1)
# [2, 4, 6, 8, 10, 12, 14, 16, 18]

リストの構造が崩れて単一のリストになってしまう。しかし、以下のように[[内側のネスト]外側のネスト]のように表記するとリスト構造が維持される。

data=[[1,2,3,4],[5,6,7],[8,9]]
result2=[[num*2 for num in alist] for alist in data]
print(result2)
# [[2, 4, 6, 8], [10, 12, 14], [16, 18]]

ちなみに、2つ上の事例でresult1=[num*2 for num in alist for alist in data]はエラーになる。やるにしても外側のネスト→内側のリストの順に書く。

  • 例えばlist_a=["呻き遊兵","梅玉幽閉","阪急梅田駅"]というリストに対して、"梅玉" in list_aとやっても、全く同一のデータがないので、Falseで返ってくるので、リストの文字列の一部があるかどうかを検索したい場合は以下のようにリストの中の文字列要素を一つづつ取り出してあるかどうかを確認することになる。
name=input("調べたい名前を入れて下さい:")
result3=False
for item in fullname:
    if name in item:
        result3=True   #あったらresult3をTrueで書き換える。
        break
print(result3)         #なければ書き換えられない元のFalseが表示され、あったら書き換わったTrueが表示
  • list_a.index("a")でaが何番目に含まれるかを表示。なければエラーが出るので、エラーが出そうな場合は例外処理を組み込んでおく。
  • list_a.count("a")でaが何個含まれるかを表示する。先ほどと同様にaxは違う扱い。
  • randomもしくはsecretモジュールのchoiceを利用すると、random.choice(list_a)とするとランダムに要素がピックアップされる。

新たな気づき(Chapter 6-2)

  • list_a.extend(list_b)はlist_a+list_bと同じ効果を得るが、list_aを不可逆に変更してしまう。list_c=list_a.append(list_b)とやってもNoneになってしまう。
  • list_a.append(list_b)はlist_aの中にリストとしてlist_bを追加。appendもlist_aそのものを不可逆にいじる。以下同様。
  • list_a.append("a")とlist_a += "a"は同じ。
  • list_a[i:j:k]で最後のiからjまでk間隔で抜き出し。
  • list_a[i:j][::k]とすると、[i:j]で抜き出したものを更にk間隔で抜き出す。list_a[::k][i:j]はk間隔で抜き出したものに対してiからjを抜き出す。[i:j:k]とも違う結果になる。
  • list_a[::-k]は逆から取り出す。
  • リストの比較はisまたは==でTrueで帰ってくると同じ。is notは同じでないならTrue
  • list_a=list_bとやったあと、list_bに変更を加えてもlist_aには変更はされない。
  • list_b=list_aをやるとisで比較するとTrueになるが、list_b=list_a.copy()、list_b=list_a[:]、list_b=list(list_a)で比較しても、中身はおなじに見えるが違うオブジェクト扱いでisで比較してもTrueにならない。

新たな気づき(Chapter 6-1)

  • list_a = [0]*10で0の10個入ったリストが作れるが、list_bもリストとすると、list_a = list_b *10もできる。
  • list("happy")やlist("日月火水木金土")のように単語をリスト化すると、結果は1文字ずつバラバラにされたリストができる。
  • list(range(0,10,2))で0-8の偶数が取れて、list(range(1,10,2))で1-9の奇数が取れる。
  • list()で空リスト生成。[]と同じ。
  • list_a[6]で7番目、list_a[-1]で一番最後の要素を取り出す。
  • list_c=[list_a,list_b]で多重リストが出来る。単層リストに要素が加わるlist_d=list_a+list_bとは違う。
  • len(list_c)は2だけど、len(list_d)はaとbの要素数の合計となる。
  • 多重リストの場合は、list_c[1]で2番目の大リスト全てを取り出し、list_c[1][0]で2番目の大リストの中の1番目の要素を取り出す。
  • リストの操作でよくあるエラーが範囲外を指定するIndexErrorなので、try〜except IndexError:構文で例外処理をすると良い。
  • list_a.append('a')でlist_aの一番後ろに追加される。
  • list_a.insert(3,'a')でlist_aの3番目の次に挿入される。
  • list_b = list_a.pop()でlist_aの最後の要素が抜き取られて削除され、list_bができる。pop(n)でn+1番目が抜き取られる。
  • list_a.remove("a")でaが削除される。これの使いみちは、リストに複数の削除したい要素が入っているときに次のように処理できる。
colors =["赤","黒","黒","黒","青","黄"]
print("削除前:",colors)
while "黒" in colors:
    colors.remove("黒")
print("削除後:",colors)
  • 文字列.split(セパレータ)で文字列あるいは文章をリストにする。例えば文章.split()とすれば文章に含まれる単語でリストが作成される(()とセパレータを指定しない場合スペースがデフォのセパレータになる)。csvファイルの行に.split(",")適用すると、pythonのリストができる。
  • del list_a[2]でlist_aの3番めを削除。del list_aでlist_aを丸ごと削除
  • "a,b,c,d,e,f,g,h,i".split(",",3)で['a','b','c','d,e,f,g,h,i']という感じのリストができる。
  • result_list="a,b,c,d,e,f,g,h,i".split(",",3)[:3]で['a','b','c']ができる。
  • セパレータ.join(リスト)で.splitの逆の操作ができる。リストから文章や文字列を再構成できる。

Python3入門ノートの感想

僕は書評とかとにかく苦手なんですけど、これはいいと思います。これなら一通り読み終えると次に進めそうな気がしてきました。みんPyに比べると、体系だってる、という感じです(スタートブックは論外)。ということで、スタートブックとみんPyをマンション1階のゴミ捨て場に放り込んできました。

新たな気付き集(Chapter 5)

条件分岐、繰り返し、例外処理のチャプターです。読み進めるほど、この本いいわあと思います。章の並びの唐突さとかがないし、関数は引数をどう入れるべきか定義っぽく示してくれるし。最初の2冊なんかいらんかったんや!時間のムダやったんや!って感じです。さて、以下備忘録です。

  • ifにifをネストするよりもif(条件式A)and(条件式B)and(条件式C)としたほうがシンプルでよい。
  • 不等式を繋げる場合は、if(a=>-5)and(a<=8)もいいけど、if -5<= a <= 8: みたいな書式も可能。Excelではできないけど。
  • Falseと同じとみなされる戻り値にNone, 0, 0.0, "", (), [], {}等がある。戻り値がTrueかFalseかで条件分岐をさせるコードは以下のように書ける。つまり戻り値がTrueだとifに続く式が実行される。
name=input("名前を入れて:")
if not name:              #上を未入力で返すとnot nameがTrueになるので次の式が実行
    name="匿名"
print(name)
from random import randint
num=randint(0,100)
if num%2:         #奇数で余りが1だとTrueになるので、次が実行される。
    result="奇数"
else:             #偶数で余りが0だとFalseになるので、上が実行されず次が実行される。
    result="偶数"
print(num,result)
  • while 条件式でループを作るが、while Trueで無限ループを作れる。普通はbreakを入れてループから抜け出せるようにする。
from random import randint
while True:
    a = randint(1,13)
    b = randint(1,13)
    if a+b==21:
        break        #合計21になったらループを出る
print(a,b)
  • while 条件式の中にcontinueを入れると、continue以下がすっ飛ばされてループが繰り返される。
from random import randint
numbers=[] #空のリストを作成
#10個の違う正の数字の入ったリストを作成
while len(numbers)<=10:
    n=randint(-10,100)
    if n<0:
        print("マイナスの数字が出たので中断されました。")
        break         #マイナスの数字が出たら中断。elseブロックすら実行されない
    if n in numbers:
        continue      #同じ数字がリストにあったら次を実行せずやり直し
    numbers.append(n)
else:
    print(numbers)
  • while〜else文の場合、whileの中にbreakがあってそれが実行された場合はelseの中は実行されない。elseはwhileをFalseで抜けた場合のみ実行される。
from random import randint
numbers=[] #空のリストを作成
#10個の違う正の数字の入ったリストを作成
while len(numbers)<=10:
    n=randint(-10,100)
    if n<0:
        print("マイナスの数字が出たので中断されました。")
        break         #マイナスの数字が出たら中断。elseブロックすら実行されない
    if n in numbers:
        continue      #同じ数字がリストにあったら次を実行せずやり直し
    numbers.append(n)
else:
    print(numbers)
  • for文もbreakで中断するとelse以降は実行されない。
  • エラー発生等例外が発生する可能性のある処理を行う場合は、tryで試し、エラーがだめならexceptをやる。エラーが出ない場合にelseの塊が実行され、finallyはエラーが出ようが出まいが実行される。
sum=300000000
while True:
    num=input(f"銀行強盗で{sum:,}円をゲットしましたが何人で山分けしますか?数字だけを入力してください。(qで終了):")
    if num=='q'or num=='q':
        print("終了しました。")
        break
    try:     #数字を入力された場合に実行
        price=sum/int(num)
    except ValueError:
        print("qか数字だけを入れろつったよな?幼稚園児かてめえ")
    except ZeroDivisionError:
        print("ゼロで割り切れると思うのか?中学校からやり直せクソ野郎")
    except Exception as error:  #上で数字以外を入れられてエラーが出た場合実行
        print(error,"ってわけわかんねえエラー出たぞボケが")
    else:
        if price<0:
            print("マイナスでどう分けようっての?馬鹿なの?死ぬの?")
            continue
        else:
            print(f"一人あたりの山分け額は{price:,.0f}円です。")
    finally: #エラーが出ようが数字以外が入力されようが実行
        print("次行ってみよう。")

新たな気付き集(Chapter 4)

入門ノートでの学習の続きです。

  • divmod(a,b)で商と余りをタプルで返す
  • pow(x,y)でxのy乗を出し、pow(x,y,z)だとそれをzで割った余りで返す。商ではない。
  • chr(整数)で整数が示すUnicodeが文字列で返る
  • ord(文字列1文字)でUnicodeが返る。
  • print(値1, 値2, sep="区切り文字", end="最後尾の文字列")
  • from モジュール名 import 関数名で特定の関数だけを読み込むとモジュール名.関数名とかしなくてもよくなる。関数名だけでよい。

文字列の操作

  • string.title()で各単語の1文字目全てを大文字にする。
  • string.count(文字列,開始位置,終了位置)である区間の文字列の個数を数える。
  • string.find(文字列,開始位置,終了位置)で文字列が何文字目かを返す.rfindで後ろから始める。
  • .findと.indexは似ているが、見つからなかったときに-1で返すか、エラーで返すかが違う。
  • string.replace(検索文字列,置換文字列,個数)で個数を指定すると最初に見つかった個数だけリプレース。以後はそのまま。
  • string.strip()で空白だの改行コードだのを除去可能
  • string.rstrip(".,\n")で末尾のピリオド、改行コードをまとめて除去可能
  • string.rstrip(".jpeg")で拡張子を取り除けるように見えるが、末尾の全てが対象なので"dog.peg.jp"だと"do"になるので要注意
  • string="信号の色には{}、{}、{}がある"をstring.format("赤","青","黄")とすると{}にそれぞれが代入される。{}に0からはじまる数字を入れるとその順番になる。
  • {}に入れるものが数字の場合{:,}と記すと三桁区切り表記になり、{:.1f}とすると小数点1位まで表記になる。{:,.2f}とすると3桁区切りと小数点2位までの表示となる。
  • fプリフィックスと呼ばれるfを""でくくる文字列の前に付加すると、以下のように書式指定が可能になる。
  • 数値の表記はnum=16797.9863をprint(f"{num:,.2f}")とすると16,797.99となる。

新たな気付き集(Chapter 3)

Pythonの基本書をまた1からはじめているのですが、1冊目(2冊目?)で定着しきれなかった事項を色々と備忘録的にメモしておく。

  • a//bで商のみを出す。round関数とか使わなくてもいい。
  • 文字列(文字列の変数)*nで文字列をn回繰り返して印字させられる。
  • string[4:4+5]だと文字列の5文字目以降5文字分をスライスできる。
  • string[開始:終了:ステップ]でステップをマイナスにすると後ろからに出来る。
  • string[::-1]だと文字列を完全に逆にできる。
  • !=はisnot演算
  • True = 1、False = 0
  • 複合代入演算子でa=a+bをa+=bでやれる。数値だけじゃなく文字列にも応用可能。数値に関しては+以外の演算子でも応用可能。


俺に必要だと思えないのですっ飛ばした事項