データ型とデータ構造

PythonPythonBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

このセクションでは、タプルと辞書の形式でデータ構造を紹介します。

基本データ型

Python にはいくつかの基本的なデータ型があります。

  • 整数
  • 浮動小数点数
  • 文字列 (テキスト)

これらについては、はじめに学びました。

None 型

email_address = None

None は、オプションまたは欠損値のためのプレースホルダとしてよく使用されます。条件分岐では False と評価されます。

if email_address:
    send_email(email_address, msg)

データ構造

実際のプログラムでは、より複雑なデータがあります。たとえば、保有株に関する情報は次のようになります。

100 shares of GOOG at $490.10

これは、3 つの要素から構成される「オブジェクト」です。

  • 株式の名称またはシンボル(「GOOG」、文字列)
  • 株数(100、整数)
  • 価格(490.10、浮動小数点数)

タプル

タプルは、一緒にグループ化された値のコレクションです。

例:

s = ('GOOG', 100, 490.1)

時には、構文で () を省略します。

s = 'GOOG', 100, 490.1

特殊なケース(0 要素タプル、1 要素タプル)。

t = ()            ## 空のタプル
w = ('GOOG', )    ## 1 つの要素を持つタプル

タプルは、単純な レコードや構造を表すためによく使用されます。通常、複数の部分から構成される単一の オブジェクト です。良い例え:タプルは、データベーステーブルの 1 行に似ています。

タプルの内容は順序付けられています(配列のように)。

s = ('GOOG', 100, 490.1)
name = s[0]                 ## 'GOOG'
shares = s[1]               ## 100
price = s[2]                ## 490.1

ただし、内容を変更することはできません。

>>> s[1] = 75
TypeError: object does not support item assignment

ただし、現在のタプルに基づいて新しいタプルを作成することはできます。

s = (s[0], 75, s[2])

タプルパッキング

タプルは、関連する項目を 1 つの エンティティ にまとめることに関するものです。

s = ('GOOG', 100, 490.1)

その後、タプルは単一のオブジェクトとしてプログラムの他の部分に簡単に渡すことができます。

タプルアンパッキング

他の場所でタプルを使用するには、その要素を変数に展開することができます。

name, shares, price = s
print('Cost', shares * price)

左辺の変数の数は、タプルの構造と一致しなければなりません。

name, shares = s     ## エラー
Traceback (most recent call last):
...
ValueError: too many values to unpack

タプルとリストの比較

タプルは読み取り専用のリストのように見えます。ただし、タプルは主に複数の部分から構成される 単一の項目 に使用されます。リストは通常、異なる項目のコレクションであり、通常はすべて同じ型です。

record = ('GOOG', 100, 490.1)       ## ポートフォリオ内のレコードを表すタプル

symbols = [ 'GOOG', 'AAPL', 'IBM' ]  ## 3 つの株式シンボルを表すリスト

辞書

辞書は、キーから値へのマッピングです。時には、ハッシュテーブルや連想配列とも呼ばれます。キーは値にアクセスするためのインデックスとして機能します。

s = {
    'name': 'GOOG',
   'shares': 100,
    'price': 490.1
}

一般的な操作

辞書から値を取得するには、キー名を使用します。

>>> print(s['name'], s['shares'])
GOOG 100
>>> s['price']
490.10
>>>

値を追加または変更するには、キー名を使用して代入します。

>>> s['shares'] = 75
>>> s['date'] = '6/6/2007'
>>>

値を削除するには、del ステートメントを使用します。

>>> del s['date']
>>>

なぜ辞書が必要なのか?

様々な値があり、それらの値を変更または操作する必要がある場合、辞書は便利です。辞書を使うことでコードが読みやすくなります。

s['price']
## vs
s[2]

ここ数回のエクササイズでは、portfolio.csv というデータファイルを読み込むプログラムを書きました。csv モジュールを使えば、ファイルを 1 行ずつ読み込むことが簡単です。

>>> import csv
>>> f = open('portfolio.csv')
>>> rows = csv.reader(f)
>>> next(rows)
['name','shares', 'price']
>>> row = next(rows)
>>> row
['AA', '100', '32.20']
>>>

ファイルを読み込むことは簡単ですが、データに対して読み込むだけでなく、さらに多くのことを行いたい場合があります。たとえば、データを保存してからそれに対して計算を行いたいかもしれません。残念ながら、データの生の「行」だけでは十分な作業ができません。たとえば、単純な数学の計算でさえうまくいきません。

>>> row = ['AA', '100', '32.20']
>>> cost = row[1] * row[2]
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type'str'
>>>

さらに多くのことを行うには、通常、生のデータを何らかの方法で解釈し、後で使えるようにもっと便利な種類のオブジェクトに変換する必要があります。2 つの簡単なオプションはタプルまたは辞書です。

演習 2.1: タプル

対話型プロンプトで、上記の行を表す次のタプルを作成しますが、数値列を適切な数値に変換します。

>>> t = (row[0], int(row[1]), float(row[2]))
>>> t
('AA', 100, 32.2)
>>>

これを使うと、今では株数と価格を掛けて総コストを計算できます。

>>> cost = t[1] * t[2]
>>> cost
3220.0000000000005
>>>

Python の数学が壊れていますか?3220.0000000000005 という答えは何でしょう?

これは、コンピュータの浮動小数点ハードウェアが 10 進数ではなく 2 進数で小数を正確に表現できるためのものです。10 進数の小数を含むたった単純な計算でさえ、小さなエラーが発生します。これは正常なことですが、初めて見るなら少し驚くかもしれません。

これは、浮動小数点を使用するすべてのプログラミング言語で起こりますが、印刷時にはしばしば隠されます。たとえば:

>>> print(f'{cost:0.2f}')
3220.00
>>>

タプルは読み取り専用です。株数を 75 に変更しようとしてこれを確認しましょう。

>>> t[1] = 75
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>

タプルの内容を変更することはできませんが、常に古いタプルを置き換える全新のタプルを作成することができます。

>>> t = (t[0], 75, t[2])
>>> t
('AA', 75, 32.2)
>>>

このように既存の変数名を再代入するとき、古い値は破棄されます。上記の代入はタプルを変更しているように見えるかもしれませんが、実際には新しいタプルを作成して古いタプルを捨てています。

タプルは、値を変数にパックしたりアンパックしたりするためによく使用されます。次のように試してみてください。

>>> name, shares, price = t
>>> name
'AA'
>>> shares
75
>>> price
32.2
>>>

上記の変数を使って、それらを再びタプルにパックします。

>>> t = (name, 2*shares, price)
>>> t
('AA', 150, 32.2)
>>>

演習 2.2: データ構造としての辞書

タプルの代替として、代わりに辞書を作成することができます。

>>> d = {
        'name' : row[0],
       'shares' : int(row[1]),
        'price'  : float(row[2])
    }
>>> d
{'name': 'AA','shares': 100, 'price': 32.2 }
>>>

この保有株の総コストを計算します。

>>> cost = d['shares'] * d['price']
>>> cost
3220.0000000000005
>>>

この例を、上でタプルを使った同じ計算と比較してみましょう。株数を 75 に変更します。

>>> d['shares'] = 75
>>> d
{'name': 'AA','shares': 75, 'price': 32.2 }
>>>

タプルとは異なり、辞書は自由に変更することができます。いくつかの属性を追加しましょう。

>>> d['date'] = (6, 11, 2007)
>>> d['account'] = 12345
>>> d
{'name': 'AA','shares': 75, 'price':32.2, 'date': (6, 11, 2007), 'account': 12345}
>>>

演習 2.3: 追加の辞書操作

辞書をリストに変換すると、そのすべてのキーが得られます。

>>> list(d)
['name','shares', 'price', 'date', 'account']
>>>

同様に、辞書に対してfor文を使って反復処理を行うと、キーが得られます。

>>> for k in d:
        print('k =', k)

k = name
k = shares
k = price
k = date
k = account
>>>

同時に検索を行うこのバリアントを試してみましょう。

>>> for k in d:
        print(k, '=', d[k])

name = AA
shares = 75
price = 32.2
date = (6, 11, 2007)
account = 12345
>>>

また、keys()メソッドを使ってすべてのキーを取得することもできます。

>>> keys = d.keys()
>>> keys
dict_keys(['name','shares', 'price', 'date', 'account'])
>>>

keys()は少し異なり、特殊なdict_keysオブジェクトを返します。

これは元の辞書のオーバーレイで、辞書が変更されても常に現在のキーを返します。たとえば、これを試してみましょう。

>>> del d['account']
>>> keys
dict_keys(['name','shares', 'price', 'date'])
>>>

'account'keysから消えたことに注意してください。再度d.keys()を呼び出さなくてもです。

キーと値を一緒に扱うよりエレガントな方法は、items()メソッドを使うことです。これは(キー, 値)のタプルを返します。

>>> items = d.items()
>>> items
dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 2007))])
>>> for k, v in d.items():
        print(k, '=', v)

name = AA
shares = 75
price = 32.2
date = (6, 11, 2007)
>>>

itemsのようなタプルがある場合、dict()関数を使って辞書を作成することができます。試してみましょう。

>>> items
dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 2007))])
>>> d = dict(items)
>>> d
{'name': 'AA','shares': 75, 'price':32.2, 'date': (6, 11, 2007)}
>>>

まとめ

おめでとうございます!あなたはデータ型とデータ構造の実験を完了しました。あなたのスキルを向上させるために、LabEx でさらに多くの実験を行って練習してください。