JavaプログラマがPythonを勉強してみた。(型について）

Javaでの投稿ネタが尽きたので、勢いでPythonの勉強を始めたJavaプログラマです。
[前回のif,for,while文の勉強記事はこちら。](https://qiita.com/riekure/items/be9d37557fb55a8258b5)

思いつきで前回投稿したのですが、過去最大数のいいね！をいただきました。
（トレンドと比べると月とスッポンですが…）
Pythonはやっぱり流行りなんだなぁと実感。

いいね！をもらえたことでテンションが上がり、
始まりはゴミみたいな理由だったけど、Pythonを真面目に勉強しよう！
それならPythonの参考書を書こう！
と思っている今日この頃。

でも、「やはり初心者向けか、思い切ってデータ分析がいいか、それともWeb開発がいいか、画像解析も捨てがたい…」
と悩んでいるので、とりあえず今は色々な入門サイトを参考にしながら、基礎中の基礎をお勉強します。

## 参考サイト
- [Python入門 - PythonWeb](https://www.pythonweb.jp/tutorial/)
- [Python入門(tohoho)](http://www.tohoho-web.com/python/index.html)
- [Python 3.6.5 ドキュメント](https://docs.python.org/ja/3/)

## 動作確認環境
- java 1.8.0
- Python 3.5.2

# 型

PHPとかちゃんと勉強した人なら苦労しないでしょうが、古臭いJava脳に、型宣言なしはツライもんです。
「パッと見て型分からん。。うぅっ。。」ってなります。
というわけで今回は型について勉強してみた。（どういうわけだ

Pythonでは、大きく分けて6種類の型(タイプ？)があるらしい。

1. 数値
2. 文字列
3. リスト
4. セット
5. タプル
6. ディクショナリ

なにやら馴染みのないものが2つくらいあります。
タプルとディクショナリってなんですか？
タプルとか聞いたことすらない…
ディクショナリは直訳すると辞書だけど、辞書型ってなんだ…

一旦おいておいて、とりあえず上から順にJavaと比較しながら勉強していきます。

## 数値
Pythonにおける数値型は以下の3つ。

1. 整数(int)
2. 長整数(long)
3. 浮動小数点数(float)

どれもJavaで見たことあるので一安心。

### int
Javaだと、

```java:IntDemo.java
int num1 = 1234; // 10進数
int num2 = 0b10011010010; // 2進数
int num3 = 02322; // 8進数
int num4 = 0x4D2; // 16進数
```

Pythonでは、

```python:IntDemo.py
num1 = 1234 # 10進数
num2 = 0b10011010010 # 2進数
num3 = 0o2322 # 8進数
num4 = 0x4D2 # 16進数
```

JavaもPythonも上から順に出力させてみると、

```
1234
1234
1234
1234
```

8進数が「0」か「0o」の小さな違いだけでした。
今のところ順調です。

### long
続きましてlongです。
Javaだと、

```java:LongDemo.java
long l = 9223372036854775807L;
```

Pythonも同じように書いてみる。

```python:LongDemo.py
l = 9223372036854775807L
```
ん？なんかエラーが出ているぞ？

```
SyntaxError: invalid syntax
```

なんでやねん！
末尾にLつけるだけじゃないかい！
と、激オコしながら[参考サイト](http://www.tohoho-web.com/python/types.html)を良く読むと、

> Python 3 では、整数(int) と長整数(long)は統合され、すべて整数(int)として扱われるようになり、L や l も廃止されました。

＼(^o^)／
上のやつはPython 2の書き方でした。
Python 3にはlongはないそうです。
参考サイトはよく読みましょう！！！！（ごめんなさい

そしてまだ重要なことが、、、
> 長整数は、メモリが許す限り桁数に制限はなく、長整数同士の演算では計算誤差も生じません。

ということで、メモリが許す限り何桁でもOKらしい。

```python:LongDemo2.py
num = 1234567890123456789012345678901234567890123456789012345678901234567890
print(num)
```
がちゃんと出力されました。

桁あふれに怯えなくていいなんて…Pythonすごすぎ…

### float

Javaでは、doubleのほうが有効桁数が多いので、floatを使うことはありません。
下のようになります。

```java:FloatDemo.java
float f = 1.2345f;
```

Pythonだと、

```python:FloatDemo.py
f = 1.2345
```

出力してみる。

```
1.2345
```

普通でした。
最大桁数はシステムに依存するとのことです。
Javaのdouble ＝ Pythonのfloatという認識で問題なさそうです。

## 文字列

続きまして文字列。

```java:StrDemo.java
String str1 = "文字列";
// 上と同じ
String str2 = new String("文字列");
```

Pythonの場合も、細かい動きまでは調べられていませんが、下のように書く。

```python:StrDemo.py
str1 = "文字列"
str2 = '文字列'
```

囲い文字は、シングルクォーテーションでもダブルクォーテーションでも良いらしいです。
QiitaとGitHubを見た限り、シングルクォーテーションを使用している方が多いような印象でした。
（Java脳は、ついダブルクォーテーションを使いたくなりますが…）

ちなみにプラス記号を使用すると、文字列連結できます。

```python:StrDemo2.py
str3 = "文字列" + "連結！"
```

## リスト
名前から想像するに、他プログラミング言語でいう配列みたいなものでしょうか？
という予想から、まずJavaで配列を書いてみる。

```java:ListDemo.java
int foo[] = [1, 2, 3, 4, 5];
```

これをPythonにすると

```python:ListDemo.py
foo = [1, 2, 3, 4, 5]
```

要素の追加、挿入、変更、削除などの機能はもちろんあります。
動きは省略しますが、まとめてみました。

|機能|使い方|
|:-----------|:-----------|
| 追加 | foo.append(6) # 末尾に6を追加 |
| 挿入 | foo.insert(5, 6) # リストの5番目の後に6を挿入 |
| 変更 | foo[5] = 6 # リストの5番目を6に変更 |

削除は、自分が調べた限り4種類ありました。

|削除機能|使い方|
|:-----------|:-----------|
| 全要素を削除 | foo.clear() |
| 指定した位置の要素を削除 | foo.pop(1) |
| 指定した値と同じ要素を削除 | foo.remove("A") |
| 位置と範囲を指定して削除 | del foo[:3] # 前にある3つの要素を削除 |

~~めんどくさかったので調査をサボりましたが、~~delは、メソッドではなく**「del文」**という構文らしい。
「変数やオブジェクトを削除する構文」とだけ覚えて、いまは次にいきます。

## ディクショナリ
直訳すると辞書だけど、辞書型ってなんだ…
tohohoの参考サイトの該当ページには、以下のように書いてあります。

> {...} は、辞書(dict)と呼ばれるキーと値のペアのリストを保持します。

JavaでいうとMapみたいなものでしょうか？？
Pythonのサンプルコードは、tohohoの参考サイトをそのまま拝借しました。

```python:DictDemo.py
d = {'Yamada': 30, 'Suzuki': 40, 'Tanaka': 80}
```

今までとは順番逆ですが、これをJavaにすると

```java:MapDemo.java
Map<String, Integer> d = new HashMap<String, Integer>();
d.put("Yamada", 30);
d.put("Suzuki", 40);
d.put("Tanaka", 80);
```

Javaは、どんな形であれput()メソッドを使用しないと値をセットできないです。
Javaに比べてPythonは、かなりシンプルに書けますね。
~~Javaほんと無能~~
Pythonの辞書型 = JavaのMapと覚えましょう。
あとディクショナリではなく、辞書型って呼び方のほうが多いようです。

## タプル
もはや聞いたことすらありません。
はじめに「タプル」でGoogle検索！
[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BF%E3%83%97%E3%83%AB)に「タプル」のページがありました。

> タプルまたはチュープル（英: tuple）とは、複数の構成要素からなる組を総称する一般概念。
> 数学や計算機科学などでは通常、順序付けられた対象の並びを表すために用いられる。個別的には、n 個でできた組を英語で「n-tuple」と書き、日本語に訳す場合は通常「n 組」としている。タプルの概念そのものも組と呼ばれる場合がある。なお、 n-tuple は数学のタプルを意味するほか、同様に double、triple などの拡張として倍数詞の表現にも利用される

＿〆（－∧－；）ん～・・・　ワカラナイィ・・・・・・・・。
算数もできないバカのお前は「Pythonを勉強するな！」って言われている気分です。（勉強するけど

すみません。本題です。

今度はPythonWebより抜粋させていただきました。

> タプル型は文字列やリスト型と同じくシーケンス型の一つです。複数の要素から構成され、要素が順に並んでいるものになります。特にリスト型とは共通している部分が多いのですが、タプルでは一度作成されたオブジェクトの要素を変更できません。またタプルにはメソッドが用意されていません

Javaで表現すると、final変数の配列(リスト)バージョンといったところでしょうか？？

実際に書いてみると、下のようになります。

```python:TapleDemo.py
tuple = (2005, 2006, 2007, 2008)
```

どうやら変更ができないので、リストより実行速度が少し早いらしい。
値を変更する予定がなければタプルを使う。それ以外はリストを使うという感じなのでしょう。

ちなみに値が1つしか持たないタプルを定義する場合は、

```python:TapleDemo2.py
tuple = (2005, )
```

と、最後にカンマを書く必要があるらしい。

# おまけ
Pythonについて調べていて「へぇ～_〆(・∀・*)」と思ったことを書いています。
タイトルに困ったので、とりあえず「おまけ」で。

## Pythonにおける定数
Pythonには、定数という概念がない。
なので、大文字とアンダーバーで構成されている変数名を定数とするのが慣例らしい。
[PEP8](https://www.python.org/dev/peps/pep-0008/#constants) に書いていました。(Google翻訳ほんと優秀

```Python
value = 1 # 可変の変数
VALUE = 1 # 定数として扱う
VALUE_MAX = 10 # 定数として扱う
```

## 文字列の型
Python 3系の場合は、文字列はunicode。
ちなみに2系だと、unicodeとstrの2種類らしい。


## 数字から始まる変数名は使えない
タイトル通り。123はダメで、hensu123はOKとのこと。

# コメントで教えていただいたこと

## カンマがあれば括弧がなくてもタプルになる

```python
value = 1, 2, 3
print(value)
print(1, 2, 3)
print((1, 2, 3))
```

実行結果は、
```
(1, 2, 3)
1 2 3
(1, 2, 3)
```

タプルになりました。
Java脳ではスッキリしすぎてて違和感ありますが、入力文字数をへらすことができるのでいいですね。

## タプルは辞書のキーに使える

タプルは不変オブジェクトなので、辞書のキーにも使えるとのことです。
また、括弧がなくてもいいので、XY座標指定のように使うこともできるらしいです。

```python
>>> a = {}
>>> a[(1, 2)] = 'abc'
>>> a
{(1, 2): 'abc'}
>>> a[1, 2]
'abc'
```

このあたりが機械学習等の統計学に役立つんでしょうか。
数学なんて忘れてしまった自分には分かりませんが…

## Pythonはすべての値がオブジェクト
Pythonはすべての値がオブジェクトとのこと。
どういうことかというと、Javaでいうプリミティブ型と参照型があるが、Pythonは全てがJavaでいう参照型みたいな感じらしいです。
なので、Pythonは数値なのにメソッドを持っているとのこと。すごい（小並感）
以下、コメントより抜粋させていただきました。

```python
>>> dir(-5)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
>>> (-5).__abs__()
5
```

dirは見ての通り、メソッド一覧を取得するものらしいです。
absは絶対値を取得するメソッドのようです。

# やってみての感想

リストとディクショナリ(辞書型)とタプルの使い方が混乱しそう。
と思ったので、表にしてみた。

|削除機能|使い方|
|:-----------|:-----------|
| リスト | []で囲む |
| ディクショナリ(辞書型) | {}で囲む |
| タプル | ()で囲む ※囲まなくてもカンマがあればOK |

自分も間違えましたが、Python2系と3系で構文や使用可能なライブラリが結構違うようです。
今から勉強を始める方は、参考文献、参考サイトのバージョンをしっかり確認しましょう。