Python入門 - シーケンス セット マッピング (2)
では、シーケンス、セット、マッピングの基本的な使い方を見ていきましょう
string (文字列)
文字列については、以前も説明をしました。ここでは、前回は説明をしなかった部分を説明したいと思います。文字列はシーケンスですので、文字列の要素である「文字」を取り出したりできます。
>>> str = 'Hello, Python!'
>>> print(str[0])
H
>>> print(str[1])
e
>>> print(str[0:5])
Hello
>>> print(str[-7:-1])
Python
>>> print(str.find('P'))
7
>>> print(str.replace('Hello', 'Hi'))
Hi, Python!
>>> print(str)
Hello, Python!
それでは、それぞれの処理を見ていきましょう。
- [n] n番目の文字(要素)を取得する nは「0」から数える
- [from: to] from番目からto番目までの部分文字列(要素)を取得する。マイナスにすると反対側から数える
- find(x) 文字xが、何番目か調べる
- replace(from, to) fromをtoに置換する
この中で、[n]とか[from: to]はリストなど、他のものでも共通です。中でも、[from: to]は一部の要素を切り取るという意味でスライスと呼ばれます。
このスライスの番号と要素の位置関係は、少しわかりづらいので図解してみようと思います。
[ 0 ] H [ 1 ] e [ 2 ] l [ 3 ] l [ 4 ] o [ 5 ]
このように、文字(要素)と文字(要素)の間に数字があるイメージです。
また、replaceの処理を見ると、置換済みの文字列は、もともとの文字列strとは別オブジェクトとして生成され、strには変更がないことがわかります。つまり、イミュータブルだ、ということです。
スライスは、省略した記法もあります。
>>> print(str[7: ])
Python!
>>> print(str[ : 5])
Hello
tuple (タプル)
それでは、タプルの使い方を見てきます。タプルは「( )」で囲い、要素を「, 」で区切って並べます。
>>> tuple = (1, 'Python', 4.4)
>>> print(tuple)
(1, 'Python', 4.4)
>>> print(tuple[0])
1
>>> print(tuple[1])
Python
>>> print(tuple[2])
4.4
>>> print(tupel[0: 2])
Traceback (most recent call last):
File "<pyshell#231>", line 1, in <module>
print(tupel[0: 2])
NameError: name 'tupel' is not defined
>>> print(tuple[0: 2])
(1, 'Python')
>>> tuple[0] = 2
Traceback (most recent call last):
File "<pyshell#233>", line 1, in <module>
tuple[0] = 2
TypeError: 'tuple' object does not support item assignment
>>> print(len(tuple))
3
要素の取り出し方や、スライスの使い方は共通です。タプルもイミュータブルなので、代入で要素を変更しようとすると、「TypeError: 'tuple' object does not support item assignment」と怒られてしまいます。
また、lenで要素数を取得できます。これは、文字列やリストなども一緒です。
>>> print(len(str))
14
list (リスト)
リストはミュータブルなので、要素の追加や削除、変更したりもできます。
リストは「[ ]」で囲います。タプルと似ているので気をつけましょう。
>>> print(len(tuple))
3
>>> print(len(str))
14
>>> list = [10, 'object', 3.33, 'data']
>>> print(list)
[10, 'object', 3.33, 'data']
>>> print(list[2])
3.33
>>> print(list[1: ])
['object', 3.33, 'data']
>>> list.append('new')
>>> print(list)
[10, 'object', 3.33, 'data', 'new']
>>> list.remove('data')
>>> print(list)
[10, 'object', 3.33, 'new']
>>> list[3] = 'old'
>>> print(list)
[10, 'object', 3.33, 'old']
>>> list.insert(2, 11.11)
>>> print(list)
[10, 'object', 11.11, 3.33, 'old']
>>> print(len(list))
5
>>> print(list.index('object'))
1
リストはミュータブルなので、代入することで、オブジェクトを変更できます。
また、新しいものがいくつが出てきたので、説明したいと思います。
- append(value) valueをリストの最後に追加する
- remove(value) valueをリストから削除する
- insert(index, value) indexの位置にvalueを挿入する
- index(value) valueが最初に出てくるのが何番目か調べる
bytes bytearray
bytesはbytes()で生成します。
>>> tuple = (10, 11, 30)
>>> b = bytes(tuple)
>>> print(b)
b'\n\x0b\x1e'
>>> b = bytes('hello', 'utf-8')
>>> print(b)
b'hello'
>>> print(hash(b))
1062589546754634676
サンプルコードのように、「整数だけのシーケンス」や「エンコードを指定した文字列」などから、bytesを生成できます。「b' '」で囲むと、それはバイト列であることを表します。
また、hash()を利用することでハッシュ値を得ることができます。
>>> ba = bytearray(tuple)
>>> print(tuple)
(10, 11, 30)
>>> print(ba)
bytearray(b'\n\x0b\x1e')
>>> ba.append(100)
>>> print(ba)
bytearray(b'\n\x0b\x1ed')
bytearrayはbytearray()で生成します。こちらはミュータブルなので、appendやremoveで要素の追加や削除ができます。
set frozenset (セットとフローズンセット)
次は、集合を見ていきたいと思います。setとfrozensetは「set([ ])」「frozenset([ ])」
で生成します。
>>> s = set([10, 20, 30, 'list'])
>>> print(s)
{'list', 10, 20, 30}
>>> s = set([10, 10, 20, 30, 'list'])
>>> print(s)
{'list', 10, 20, 30}
>>> print(s[0])
Traceback (most recent call last):
File "<pyshell#60>", line 1, in <module>
print(s[0])
TypeError: 'set' object does not support indexing
>>> s.add(100)
>>> print(s)
{'list', 100, 10, 20, 30}
>>> s.remove('list')
>>> print(s)
{100, 10, 20, 30}
>>> fs = frozenset([1, 2, 3])
>>> print(fs)
frozenset({1, 2, 3})
セットは重複を認めないので、同じ値が複数あっても、1つだけになります。
また、順序がなく、シーケンスと違い、生成時の要素の順番は関係ありません。順番がないので、[n]で要素にアクセスできません。n番目の要素が何かわからないからです。
また、要素の追加や削除もできます。
- add(value) valueを追加する
- remove(value) valueを削除する
dictionary (辞書)
辞書は、{キー:値, キー:値}という書き方で、生成します。
>>> dictionary = {'apple': 'red', 'banana': 'yellow', 'mikan': 'yellow'}
>>> print(dictionary)
{'apple': 'red', 'banana': 'yellow', 'mikan': 'yellow'}
>>> print(dictionary['banana'])
yellow
>>> print(dictionary['mikan'])
yellow
>>> print(len(dictionary))
3
>>> dictionary.update('tomato': 'red')
SyntaxError: invalid syntax
>>> dictionary.update({'tomato': 'red'})
>>> print(dictionary)
{'apple': 'red', 'banana': 'yellow', 'mikan': 'yellow', 'tomato': 'red'}
>>> del dictionary['apple']
キーを指摘することで、値を取得できるのがわかると思います。また、要素の追加削除は下記の通りにします。
- updete() 要素を追加する
- del XXX[キー] 要素を削除する
Python入門 - シーケンス セット マッピング (1)
複数のオブジェクトを集めたデータ型
データには、複数のオブジェクトが集まったものがあります。例えば、数値は、それ自体で1つのオブジェクトです。しかし、文字列は複数の「文字」というオブジェクトが「順番」に並んでできたオブジェクトと言えます。文字列のように、複数のオブジェクトを扱うためのデータ型がPythonには、たくさん用意されています。
これは、Pythonのおおきな特養の一つです。
記事が長くなってしまうため、ここでは内容の解説だけにして、文法やサンプルコードは別の記事にしたいと思います。
それでは、順番に見ていきましょう。
シーケンス(順序型)
シーケンスは順序のあるオブジェクト(要素)の集まりです。シーケンスには1度生成すると変更できない不変(イミュータブル immutable)なものと、後からでも変更できる可変(ミュータブル mutable)なものがあります。シーケンスは順序があるため、個々の要素の値が一緒でも、順序が違うと別オブジェクト扱いです。
不変(イミュータブル)
不変なシーケンスは3種類あります。
- string (文字列)
- tuple (タブル)
- bytes
可変(ミュータブル)
可変なシーケンスは2種類です。
- list (リスト)
- bytearray
それでは、それぞれについて説明していきたいと思います。
string (文字列)
Unicodeの文字列です。それぞれの「1文字」はU+0000 - U+10FFFFで表現されます。文字列を、それぞれの文字を0 - 10FFFF(16進数)に変換したり、「文字列」を、その数値データが並んだ「bytes」に変換したり、逆に「bytes」を「文字列」に変換したりできます。
ちなみに、Pythonには、いわゆる「char」型はありません。
tuple (タブル)
タプルは、複数のデータを1つにまとめたものです。タプルにできるデータの種類や数は任意です。いくつかのデータを、とても気軽にグループにまとめることができます。
タプルは不変なデータ型のため、一度作ると、後から変更することはできません。
変更しないデータを扱うのに向いています。
list (リスト)
リストは、いくつかのデータを順番に並べたものです。リストを構成するデータ(リストの要素)は、タプルと一緒で、種類や数は自由です。
タプルとの違いは、後から変更できることです。つまり、要素を追加したり、削除したり、並び替えたりできます(シーケンスは順序に意味があるため、要素が同じでも順序が違うと別のオブジェクトです)。
bytesとbytearray
bytesとbytearrayは、どちらもバイトデータが順番に並んだもの(シーケンス)です。基本的な機能や、その機能の使い方(インターフェース)は一緒です。違うのは、もちろん変更できるかできないかです。
変更できないbytesにはハッシュの機能があり、bytearrayは要素の変更や追加削除ができます。
セット (集合型)
セットタイプは、重複を許さない要素の集まりです。すでにセットに含まれているオブジェクトを、別にもう1つ追加しようとしても追加できない、ということです。また、要素の順番も関係ありません。
すでにシーケンスがあるのに、なぜセットが必要なのかわかりにくいかもしれませんので、セットの主な用途を並べておきまs。
- オブジェクトが、ある条件を満たしたものの集まりに属しているかどうかを高速に調べる(絶対に重複がないので、高速に調べられる)
- シーケンスから、重複した要素をなくす。
- 和集合や積集合といった、数学的な集合の計算をする
- この後で説明するmap (辞書型)のキーにする
セットには、可変なものと不変なものが、それぞれ1つずつ用意されています。
- set (セット 可変)
- frozen set (フローズンセット不変)
setとfrosen setの違いは、bytesとbytearrayと同じです。基本的な機能は共通ですが、setは要素の追加や削除ができ、frosen setはハッシュを利用することができます。
マッピング
マッピングは「インデックス」のセットと、「インデックスに対応するオプジェクト」の組が要素として集まったものです。
マッピングは、なかなかピンとこないと思います。そこで、具体例として辞書を考えてみるとわかりやすいと思います。辞書は、「見出し語」と「見出し語の説明」の組が要素となって構成されています。「見出し語」が「インデックス」で「見出し語の説明文」が「インデックスに対応するオブジェクト」です。辞書では、「見出し語」は重複しません。もし同じ見出し語が2つあったら、どちらを見たらいいかわからなくなってしまうからです。また、「見出し語」は、比較的短いため、「見出し語一覧」から検索するのも簡単です。
この「辞書」のような構造のモデルをプログラムのデータ型にしたのが「マッピング」というわけです。
Pythonには、もともと組み込まれているマッピングは1つしかありません。その名もズバリ、
- dictionary (辞書型)
です。
dictionaryは可変であり、インデックスのことを「キー」と呼びます。
「キー」は、先ほど説明した通り、「セット」でなければなりません(重複があると困るからです)。
一部のデータ型は、この「キー」にすることができません。「キー」にすることができたにデータ型は以下の通りです。
- list
- dictionary
- オブジェクトが一致するかどうかを比較するときに、オブジェクトの同一性でなく値で比較するもの
最後のは、よくわからなければ「ふーん、そんな条件があるんだ」くらいに思っておいていただければいいと思います。
Python入門 - 比較と論理
数値の大きい、小さいを比べる
Pythonでは、数値の大小を比較することができます。書き方はJavaなどと変わりありません。その結果は「true(真)」「false(偽)」で表現されます。
そうして、比較をした結果にょって、実行する処理を分岐させたりします。
>>> 10 > 5
True
>>> 5 > 10
False
>>> 1.1 == 1.1
True
>>> 1.1 != 1.1
False
>>> 10 >= 10
True
>>> -10 <= 0
True
比較には「==(等号)」「!=(不等号)」「>(大なり)」「>=(以上)」「<(小なり)」「<=(以下)」があります。
その「比較をしている式」が正しければ、結果が「true」、間違っていれば「false」です。
もちろん、直接数値を比較するだけでなく、変数を使ったり、「( )」を利用して計算しながら比較することも可能です。また、比較した結果を、もう一度変数に代入することもできます。
>>> num1 = 10
>>> num2 = 20
>>> result = num1 < num2
>>> print(result)
True
>>> result = (num1 * 3) < num2
>>> print(result)
False
文字列の比較
数値以外にも、文字列も比較をすることができます。
>>> 'python' == 'python'
True
>>> 'Python' == 'python'
False
>>> 'aka' < 'ao'
True
>>> 'yellow' < 'blue'
False
「==」は大文字、小文字も区別して、文字列が一致しているかどうかを調べます。
大きい、小さいの比較は辞書順の比較結果になります。
論理演算をする
プログラムをしていると、「5以上、10以下」のように、いくつかの比較を組み合わせたいシーンが、よく出てきます。また、条件を否定したい場合もあります。
そのような場合には、2つの条件を組み合わせる場合は、論理演算子「and」「or」を利用します。ある条件を否定する場合は、「not」を使います。
>>> num1 = 5
True
>>> (3 < num1) and (num1 < 10)
True
>>> num2 = -1
>>> (num2 < 0) or (10 < num2)
True
>>> not (num2 < 0) or (10 < num2)
False
論理演算は、結果がどうなるのか、慣れるまでわかりにくいかもしれません。
以下が、論理演算の入力値と、その結果の一覧表です。
and 論理積
値1 | 値2 | 結果 |
---|---|---|
true | true | true |
true | false | false |
false | false | false |
or 論理和
値1 | 値2 | 結果 |
---|---|---|
true | true | true |
true | false | true |
false | false | false |
not 否定
値1 | 結果 |
---|---|
true | false |
false | true |
文字列 前 | Python入門 | 次 シーケンス セット マッピング (1)
Python入門 - 文字列
Pythonで文章を書く
Pythonで扱えるデータには数値の他にも「文字列」があります。「'」「"」で囲った部分が文字列になります。
>>> print('I am programmer!')
I am programmer!
>>> print("I am programmer!")
I am programmer!
>>> print('110')
110
>>> print('090-XXXX-YYYY')
090-XXXX-YYYY
このように、数値も「'」「"」で囲えば文字列です。変数ももちろん使えます。
>>> iam = 'I am '
>>> prog = 'programmer!'
>>> print(iam + prog)
I am programmer!
数値だと「+」は普通の足し算ですが、文字列では2つの文字列をくっつけた文字列になります。
ここで1つ、Python(というかIDLE)の弱点があります。日本語に弱いのです。私は現在MacでIDLEを使っているのですが、直接、日本語を入力できないのです(わざわざ別の場所で書いたものをコピへしています)。Python3 では、文字列はUTF-8で表現されます。
エスケープシーケンス
文字列でアルファベットや数値、ひらがなを書くのは問題ありませんが、特殊な文字を表すことができません。これを解決するのがエスケープシーケンスです。「¥」(日本語キーボードでは円記号、英語キーボードではバックスラッシュ)を最初につけることで、特殊な文字を表すことができます。
- \\ 「\」バックスラッシュ
- \'「'」シングルクォーテーション
- \" 「"」ダブルクォーテーション
- \a ベル(ベル音を鳴らす)
- \b バックスペース
- \f 改ページ フォームフィード
- \n 改行 ラインフィード
- \r キャリッジリターン
- \t 水平タブ
- \r 垂直タブ
- \N{name} Unicodeデータベースで名前nameを持つ文字(Unicodeのみ)
- \uxxxx 16ビットの値で表されるUnicode文字(xxxxは16進数)
- \Uxxxxxxxx 32ビットの値で表されるUnicode文字(xxxxxxxxは16進数)
- \ooo 8進数で表されたASCIIコード(oooが8進数)
- \xhh 16進数で表されたASCIIコード(hhが16進数)
- \0 NULL文字
>>> print('i\'m programmer!')
i'm programmer!
>>> print('Hello\n\tWorld!')
Hello
World!
>>>
Python入門 - 変数
変数を使う
Pythonでは、JavaやCと違い、データ型をコード上で指定をしません。プログラムが実行されるときに、自動的にどんなタイプのデータか判別しれくれます。これを動的型付けと言います。
>>> num1 = 13
>>> num2 = 7.5
>>> print(num1)
13
>>> print(num2)
7.5
>>>
変数num1とnum2にそれぞれ代入した値が入っているのがわかると思います。変数の使い方は次のようになります。
変数 = 値
「=」は、普通の数学だと等号で、右と左が同じことを表しますが、Pyhonでは右の値を左の変数に代入することを意味します。統合は「==」とイコールを2つ並べたものになります。
>>> num3 = num1 + num2
>>> print(num3)
20.5
これは、変数num1、num2を足して、新しい変数num3に代入しています。変数は値を保存したり、値にどんな値か名前をつけたりする意味があり、プログラムをする上でとてもよく使うものです。しっかり使い方を押さえておきたいですね。
基本的な変数と代入の使い方
それでは、いろいろな変数の使い方を見てみましょう。
>>> num1 = 10
>>> num1 = num1 + 10
>>> print(num1)
20
>>> num2 = 10
>>> num2 += 10
>>> print(num2)
20
>>> num3 = 4
>>> num3 *= 2
>>> print(num3)
8
一番上の「num1 = num1 + 10」という書き方は、初め違和感があるかもしれません。ですが、Pythonでは「=」はあくまで代入という意味です。ですので、これは「num1に10を足して、その結果をもう一度num1に代入する」という式になります。
そのあとの「num2 += 10」は「num2に10を足す」という代入式です。他にも「-=」「*=」「/=」もあります。
ちなみに、JavaやCにある「++」「--」はPythonにはありません。「num1 += 1」などと書くようにしましょう。
>>> num5
Traceback (most recent call last):
File "<pyshell#108>", line 1, in <module>
num5
NameError: name 'num5' is not defined
また、このように変数だけを先に宣言することもできません。「not defined」と言って怒られてしまいます。
Pythonでは、たくさんの変数に対して、いっぺんに代入を行うこともできます。
>>> a, b, c = 0, 1, 2
>>> print(a)
0
>>> print(b)
1
>>> print(c)
2
これまで、数値をメインに説明してきましたが、次から文字列など数値以外のデータ型について説明していきたいと思います。
Python入門 - 数値と算術演算
まずは、Pythonで電卓する
習うより慣れろで、さっそくコードを書いて実行してみましょう。コード量が少ないので、インタラクティブモードでいろいろ試してみたいと思います。
>>> 6 + 6
12
>>> 6 + 3
9
>>> 6 + 3 * 2
12
>>> (6 + 3) * 2
18
>>> 4 * -11
-44
>>> 7 / 3
2.3333333333333335
>>>
だいたい、直感通りに計算できます。気をつけたいの/」の割り算で、これは計算結果が小数になります。カッコで囲っていなくても、「*」「/」が「+」「-」よりも優先されます。
>>> 11 / 3
3.6666666666666665
>>> 11 // 3
3
>>> 11 % 3
2
>>> 1.3 + 4
5.3
>>>
「//」は割り算の結果の小数部分を切り捨てて、整数にします。「%」は剰余です。剰余は聞きなれない言葉ですが、要するに割り算の余りのことです。そんなの何に使うのかと思われるかもしれませんが、数字が奇数か偶数かを判別したり、4の倍数かどうかを判断するのに使います(4で割った余りが0なら4の倍数とわかる)。また、整数と小数の足し算結果は小数になります。
その他の演算
Pythonには、他にも様々な計算があります。
>>> 5 ** 2
25
>>> ~4
-5
>>> -(4 + 1)
-5
>>> 4 >> 1
2
>>> 4 << 1
8
>>> 2 & 3
2
>>> 2 | 3
3
>>> 2 ^ 3
1
「**」はべき乗の計算です。5の2乗で25というわけです。
そのあとの演算は「ビット演算」というものです。コンピュータでは数値は内部的には0、1のビッドで表されています。このビットに対して演算します。
「~」はビット反転で0を1に1を0にします。「>>」「<<」は右/左シフトで各ビットをそれぞれ右/左に指定した数だけずらします。「&」「|」「^」はそれぞれ論理積、論理和、排他的論理和です。
IDLEとPythonの基本的な使い方 前 | Python入門 | 次 変数
Python入門 - IDLEとPythonの基本的な使い方
IDLEを使ってみる
それでは、インストールしたIDLEを起動してみましょう。
IDLEを起動すると、「Python 3.x Shell」(以下、シェル)という画面が立ち上がります。このシェルでは、インタラクティブモードになっています。プログラムを打ち込むと、すぐにその場で実行されます。1行ずつ入力するたびに実行されます。
print('Hello World!')
Hello World!
>>>
とても気軽にプログラムを実行できるので、ちょっとしたプログラム(コードスニペットとも言います)を試すのじぴったりです。
pyファイルを作って実行する
しかし、これではプログラムを保存したり、同じプログラムを何度も実行したりするのにはとても不便です。そこで、コードを別ファイルに書くようにします。
IDLEのメニューから「File」→「New File」を選択します。そうすると、別画面が出てくるので、この画面に同じようにプログラムします。この画面上では、インタラクティブモードと違い、入力するごとに実行されるということはないので、たくさんまとめてプログラムすることができます。
print('Hello World')
sum = 2 + 4
print(sum)
作ったプログラムは実行する前に、保存しておく必要があります。名前はなんでもOKですが、拡張子は「.py」になります。プログラムを保存したら、さっそく実行しましょう。メニューの「Run」→「Run Module」で実行できます。このプログラムの実行結果は以下のようになります。
Hello World
6
エラーメッセージの見方
プログラムにバグがある場合、プログラムは一部しか実行されず、エラーになります。
例えば、下記のプログラムはバグのあるプログラムです。
print('Error Test')
sum = 2 + 'one'
このプログラムを実行すると、シェルにエラーメッセージが表示されます。
Error Test
Traceback (most recent call last):
File "*****/FirstProgram.py", line 2, in <module>
sum = 2 + 'one'
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Pythonは、プログラムのコードを1行ずつ実行するインタプリタと呼ばれるタイプの言語です。ですので、プログラムの正しい行は実行され、間違ったところでエラーになって止まります。
このエラーメッセージは、「*****/FirstProgram.py
」というファイルの2行目の「sum = 2 + 'one'
」で「TypeError: unsupported operand type(s) for +: 'int' and 'str'
」というエラーが起きていますよ、という意味です。
Pythonの準備をする 前 | Python入門 | 次 数値と算術演算