python collections namedtuple

Python学習【365日チャレンジ!】279日目のマスターU(@Udemy11)です。

そういえば最近現金をほとんど持ち歩かなくなりました。

電子決済ができる店舗が飛躍的に増えて、キャンペーンなどで○○%ポイント還元をやっているので、現金を使うより断然お得なんですよね。

とはいえ、まだキャッシュレスよち現金支払いの方が割引してくれる店舗があって、その時は現金を持っていなかったので、ちょっと損した気分になってしまいました。

まだ小銭入れに数千円程度の現金は持っておいたほうがいいかもしれませんね。

では今日も、Python学習を始めましょう。

昨日の復習

昨日は、メモリを効率よく扱ってデータのイン・アウトが高速に処理できるdequeを学習しました。

dequeを使うことで、中に入れた辞書型データの値を簡単に加工して使いやすい形にすることができました。

値の追加ももちろんできますが、値の最後に追加されるので、値を追加したら、再度加工する必要がありました。

詳細については昨日の記事をごらんください。

今日は、タプルを拡張させたような使い方ができるnamedtupleを学習します。

tupleを復習

tupleは、下記の記事で学習していますが、namedtupleを学習する前に、少しだけtupleを復習します。

まず簡単なタプルを定義して値を出力してみます。

p = (10, 20)
print(p[0]) #出力は10
p[0] = 100 #書き換えられないのでエラーが起こる

1行目でpにタプルを入れて、2行目でインデックスが0の値を出力しています。

3行目は、インデックスが0の値を100に書き換えようとしていますが、タプルなので、エラーが起こります。

次にタプルもどきのクラスを作ってみます。

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
p = Point(10, 20)
print(p.x) #出力は10になる
p.x = 100
print(p.x) #前の行で値が書き換えられて100になる

1行目でPointクラスを作って、2行目から4行目でxyを引数に指定しています。

6行目で引数を1020にしたオブジェクトを作成し、7行目で最初の引数xを出力して、8行目で引数x100に書き換えた後、9行目で再度出力しています。

タプルではないので、最初に入れた引数が簡単に書き換えられてしまいます。

namedtuple

namedtupleを使えば、このクラスのようにデータを入れられて、値は書き換えられない属性を持ったデータを作成することができます。

言葉ではうまく説明できないので、実際にコードを書いてみます。

import collections

Point = collections.namedtuple('Point', ['x','y'])
p = Point(10, 20)
print(p.x)
p.x = 100 #書き換えられないのでエラーが起こる

3行目のcollections.namedtupleで、オブジェクト名Pointと引数['x','y']を指定したPointを作成しています。

この時の引数の指定はリストにしていますが、文字列として'x, Y'としても問題はありません。

4行目で引数に1020を入れたオブジェクトを作成して、5行目で引数xを出力しています。

6行目はコメントアウトしていますが、引数xの値を書き換えようとするとエラーが起こります。

_makeと_asdict

namedtupleのオブジェクトを作る際は_makeを使います。

p1 = Point._make([100, 200])
print(p1) #出力結果:Point(x=100, y=200)
print(p1._asdict()) #出力結果:{'x': 100, 'y': 200}

先ほどのコードの続きを4行目から記述しています

4行目でp2オブジェクトを、_makeを使って作成し、5行目でp1を出力しています。

6行目の_asdictは引数に対応する値をマッピングした辞書型データを返すメソッドです。

5行目、6行目ともに右に記述しているデータが出力されます。

_replace

_replaceは、namedtupleのオブジェクトの値を置き換えてくれます。

p1 = Point._make([100, 200])
p1._replace(x=500)
print(p1) #出力結果:Point(x=100, y=200)

p2 = p1._replace(x=500)
print(p2) #出力結果:Point(x=500, y=200)

4行目で_makeを使ってxy100200を代入したオブジェクトを作成しています。

5行目で_replaceで値を変更しているような感じですが、6行目の出力を見るとp1は変更されていません。

この_replaceは、クラスの継承のような感じで、すでにあるオブジェクトから新しいオブジェクトを作成するときに値を変更するという使い方ができます。

8行目でp1をもとにして、xの値を変更した新しいp2オブジェクトを作成するような使い方をすれば、新しいオブジェクトの値が変更されているのがわかるかと思います。

まとめ

酒井さんの講座を受講しながらPython学習を進めていますが、現時点(2020年11月16日)でのPythonの最新バージョンは3.9です。

レクチャーは、Python3.6で解説されているので、出力が若干違ったり、メソッドなどの仕様が少し変更されたりしています。

このことを理解していないと、変なところではまってしまうので、公式ドキュメントやネット上の新しい情報を収集しながら、学習を進めていく必要があります。

とはいえ、基本は同じなので学習効果は得られますし、何といってもこれだけ広くPythonの学習内容をカバーしているのでPythonを学習するにはもってこいの講座です。

もうすぐブラックフライデーセールも始まるかと思うので、ぜひこの機会に受講してみてください。

Udemy講師 酒井さん プログラミング Python

それでは、明日もGood Python!