【随時追記】今夜寿命を迎えても良いようにPythonの基礎学習内容をメモしとく。

# 概要

__Java脳__だった私も遂に__Pythonデビュー__したので、__小さいこと__から__お便利テクニック__まで、個人的に__これはメモだ！__と思ったことを__独断と偏見で世間に発信していく__だけの記事を作りました。

__殴り書きレベル__にまとめて行きますのでご了承ください。orz

# コーディング関連

## import関連

import文は基本的にはファイルの最初にまとめておきましょう。
Pythonにもいくつかのimport文が存在しています。

### 通常

以下のようにモジュールを__import__する事が出来ます。

```py:通常
import math
 
print('円周率 -> {}'.format(math.pi))  # 円周率 -> 3.141592653589793
```

### 別名(as)

importしたモジュールに__別名__をつけて使う事が出来ます。

```py:別名
import math as mathUtil
 
print('円周率 -> {}'.format(mathUtil.pi))  # 円周率 -> 3.141592653589793
```

### From(as)

importしたいモジュールの中から__メソッド__や__クラス単位__で読み込む

以下のようなモジュールがあった場合、

```py:myModule.py
class Hello():
    def world(self):
        return 'Hello,World!!'

def hoge():
    return 'fuga'
```

以下のように記述が出来ます。
__記述時の冗長化を取り除く__事が出来ます(特に__クラス利用時__)。

```py:From
import myModule
print(myModule.Hello().world())  # Hello,World!!

import myModule
print(myModule.hoge())  # fuga

from myModule import Hello
print(Hello().world())  # Hello,World!!

from myModule import hoge
print(hoge())  # fuga
```

## print関連

### 通常通常出力

単純に文字列を出力したい場合は__print関__数を利用します。

```py:通常出力
print("通常出力")
```

### インスタンス出力

ただ、__インスタンスの状態__を出力したい場合、単純に__print関数__に渡すと、

```py:インスタンス出力(ダメな方法)
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def myNameIs(self):
        return self.name

person = Person("Taro", 20)
print(person)  # <__main__.Person object at 0x101172588>
```
のように、__インスタンスオブジェクトの情報__しか表示されません。

なので、__vars関数__をかませることで__インスタンス内の値__を表示することが出来ます。

```py:インスタンス出力(正しい方法)
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def myNameIs(self):
        return self.name

person = Person("Taro", 20)
print(vars(person))  # {'name': 'Taro', 'age': 20}
```

## クラス関連

### 定義方法

__クラスを作る__場合は以下のように定義することが出来ます。

```py:クラス定義
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def myNameIs(self):
        return self.name

person = Person("Taro", 20)
print(person.myNameIs())  # Taro
```

## 変数関連

### 変数の型

Pythonは__動的型付け__なので、Javaのように変数定義時に__型を指定する必要がありません__。
また、JavaScriptのように__var等__すらも不要です。

```py:Python
name = '太郎'
```
```java:Java
String name = "太郎";
```
```javascript:JavaScript
var name = "太郎";
```

### 大文字と小文字の区別

Pythonは変数名の__小文字__と__大文字__を__区別__します。

```py:var
hoge = "fuga"
print(Hoge)
# NameError: name 'Hoge' is not defined
```

## インデント

Pythonでは__行頭スペースのライン__でブロックが決まります。
一般的には__スペース4個__単位でインデントを取るのが基本らしいです。

他の言語と同様にタブも使えるようですが、__同じインデントを表す際に、<font color="red">スペースとタブの差異があるとエラー</font>__が出てしまいます。
ちなみに、タブは内部的に__スペース8個分__と同じラインになってしまうので、__あまり推奨されていない__そうです。

```py:エラー
for element in {1,2,3}:
	print ("タブx1") 
        print ("スペースx8")  # inconsistent use of tabs and spaces in indentation

for element in {1,2,3}:
    print ("スペースx4") 
    print ("スペースx4")
    if element == 2:  # タブx1
	 print ("タブx1 + スペースx1")  # inconsistent use of tabs and spaces in indentation
```
```py:正常
for element in {1,2,3}:
	print ("タブx1") 
	print ("タブx1")
	if element == 2:  # タブx1
         print ("スペースx9")  # インデント上はタブ　＝　スペース8個分なので合計スペース9個以上ならOK

for element in {1,2,3}:
	print ("タブx1") 
	print ("タブx1")
	if element == 2:  # タブx1
	 print ("タブx1 + スペースx1")  # インデント上はタブ　＝　スペース8個分なので合計スペース9個以上ならOK

for element in {1,2,3}:
    print ("スペースx4") 
    print ("スペースx4")
    if element == 2:  # スペースx4
    	print ("スペースx4 + タブx1")  # 合計スペース5個以上ならOK
```

__<font color="red">※Qiita上ではズレてますが、処理上はスペース8個とタブ1個でラインは揃いますorz</font>__

__要するに、Pythonではタブインデントはやめましょうw__

## セミコロン

Pythonではセミコロンがない場合、__その行全てが一つの処理__とみなされます。
もちろん、セミコロンをつけても良いですが別につけなくても__エラーにはなりません。__だいたい皆付けていません。

```py:Python
print ("Hello")   # どちらも同じ
print ("Hello");  # どちらも同じ
```

また、__意図的__にセミコロンを入れることで__複数の処理を一行にまとめる__ことも出来ます。
ただ、この記述方法はあまり__<font color="red">推奨されていない</font>__ので、特別な利用がなければ、__１処理１行__にまとめた方が良いでしょう。

```py:Python
print ("Hello."); 
print ("World!");  # どちらも同じ
print ("Hello."); print ("World!");  # どちらも同じ
```

## 複数行記述

長い処理の場合、一行にすると横に長くなってしまい非常に見にくいです。
そんな時は「\」を使って複数行に渡って記述をすることが可能です。

ただし、 __丸/波/角括弧__の中は__常に継続__と判断されるので 「\」 は__不要__とのことです。
(@shiracamus さんご指摘ありがとうございます！)

```py:複数行
result = 1 + \
 2
print(result)  # 3

print(1 + 2)  # 3
print(1 +
                  2)  # 3

```

## シングルクウォートとダブルクウォート

Pythonでは__シングルクウォート__でも__ダブルクウォート__でも基本的にはどちらでも良いです。
お好きな方を使いましょう。

```py:引用符
single = 'single'  # 同じ
double = "double"  # 同じ
print(single)
print(double)

```

文字列中に引用符を入れる場合は、__囲んでない引用符__を使う場合と__エスケープ__する２つの方法があります。

```py:引用符２
single1 = 'this is "single1."'  # 同じ
double1 = "this is 'double1.'"  # 同じ
print(sinble1)
print(double1)

single2 = 'this is \'single2.\''  # 同じ
double2 = "this is \"double2.\""  # 同じ
print(single2)
print(double2)

```

## コメント関連

### 単一行

単一行は、__#__を使うことで以降の記述をコメントアウトすることが可能になります。

```py:単一行コメント
# これはコメント
print("Hello, world!") # これもコメント
```

### 複数行

厳密には、複数行文字列(ヒアドキュメント)との事です。
複数行にわたるコメントを記述する際に利用されています。

複数行コメントは__シングルクウォートまたはダブルクウォート３つ__で記述可能です。
(@shiracamus さんご指摘ありがとうございます！)

```py:複数行コメント
'''
print(hoge)
print(hoge)
'''
"""
print(fuga)
print(fuga)
"""
```

## if文

Pythonのif文の書き方はちょっと__特殊__です。

```py:Python
if value == 1:
    print('valueの値は1です')
elif value == 2:
    print('valueの値は2です')
elif value == 3:
    print('valueの値は3です')
else:
    print('該当する値はありません')
```
```java:Java/JavaScript
if( value == 1 )
    System.out.println("valueの値は1です");
else if( value == 2 )
    System.out.println("valueの値は2です");
else if( value == 3 )
    System.out.println("valueの値は3です");
else
    System.out.println("該当する値はありません");
```

また、__複合条件__も__and/or__を使うことで簡単に指定することが出来ます。

```py:複合条件
if value == 1 and value == 2 - 1:  # どちらも満たす場合
    print('valueの値は1です')
elif value == 1 or value == 2:  # いずれかを満たす場合
    print('valueの値は1か2です')
else:
    print('該当する値はありません')
```

条件によって何もしたくない場合は__pass__でスキップすることも出来ます。

```py:スキップ
if value == 0:
    pass  # 何もしない
elif value == 1 and value == 2 - 1:
    print('valueの値は1です')
elif value == 1 or value == 2:
    print('valueの値は1か2です')
else:
    print('該当する値はありません')
```

## for文

for文もif文と似ています。
もちろん、__break/continue__も使えます。

```py:for文
for element in array:
    print(element)
```

また__for-else__という構文も使えます。

```py:for-else文
for element in array:
    print(element)
    if element == 2 :
        break
else:
  print("End")  # for文が終了した際に一度だけ実行されるが、breakの際には実行されない
```

@wakamezake さんご指摘ありがとうございます！

### enumerate関数

ループの中で__index番号__を取得したいケースは少なからずあります。
その場合は、__enumerate関数__を使うことで実現可能です。
__※indexは<font color="red">0スタート</font>です。__

```py:indexの取得
for index, element in enumerate(array):
    print(element)
    if index > 3 :
        break
```

## コレクション関連

### リスト(list)

複数のデータを__まとめて管理__する事が出来ます。
リストを定義するには__角括弧（[]）__を使って表し、要素を__カンマ（,）__で区切ります。

```py:リスト
list = ["yamada","tanaka","takahashi"]
print(list)  # ['yamada', 'tanaka', 'takahashi']
```

### タプル(tuple)

タプルを定義するには__括弧（()）__を使い、要素を__カンマ（,）__で区切りで並べます。
また、__括弧を使わなくても__定義することは可能です。
が、__<font color="red">可読性を上げる</font>__ために__括弧で囲む__ようにしましょう。

リストとタプルの違いは

- __イミュータブル(不変)__
- __実行速度がリストよりちょっとだけ早い__

です。

```py:タプル
tuple = ("yamada","tanaka","takahashi")
print(tuple)  # ('yamada', 'tanaka', 'takahashi')

tuple = "yamada","tanaka","takahashi"
print(tuple)  # ('yamada', 'tanaka', 'takahashi')
```

### 辞書(dictionary)

__ディクショナリ型__とは、「__{}__」の中に__key/value__の組み合わせで表すデータのことです。
基本的には__JSON形式__と同じですが、Pythonではディクショナリ型として取り扱います。

Keyが存在しない値を指定すると__<font color="red">エラー</font>__になるので気をつけてください。

```json:test.json
{
  "yamada":{
    "age":20,
    "sex": "male"
  },
  "tanaka":{
   "age": 19,
   "sex": "female",
   "mailAddress": "XXXX@XXXX"
  }
}
```
```py:dic.py
import json

testJson = open('test.json', 'r')
jsonDict = json.load(testJson)
print(jsonDict)  # {'tanaka': {'age': 19, 'mailAddress': 'XXXX@XXXX', 'sex': 'female'}, 'yamada': {'age': 20, 'sex': 'male'}}


print(jsonDict['yamada'])  # {'sex': 'male', 'age': 20}
print(jsonDict['yamada']['age'])  # 20

print(jsonDict['yamada']['mailAddress'])  # KeyError: 'mailAddress'

print('jsonDict:{}'.format(type(jsonDict)))  # jsonDict:<class 'dict'>

jsonStr = json.dumps(jsonDict)
print('jsonStr:{}'.format(type(jsonStr)))  # jsonStr:<class 'str'>
```
### 集合(set)

リストやタプルのように__値__しか持ちませんが、__<font color="red">順序も持たず</font>__1つの集合内には同じ値が__1つしか__持てません。
なので、__一意な値を管理__する際に非常に便利です。

集合を定義するには、__波括弧（{ }）__で囲んだ中に、要素を__カンマ（,）__で区切って指定して定義します

```py:リスト
set = ["yamada","tanaka","takahashi"]
print(set)  # {'yamada', 'tanaka', 'takahashi'}
```

## 内包表記

Pythonには「__内包表記__」という概念があります。
これは、__リスト__や__ディクショナリ__を__シンプルに記述する方法__の事を指しています。

内包表記を用いると、__複数行に渡す記述__を__まとめて1行__で書く事が可能になり非常に便利です。

慣れるまでは大変ですが、Pythonを覚えれるのであれば頑張って使いこなせるようになりましょう！

### リスト内包表記

以下は同じです。

```py:リスト内包表記
result = []
for element in range(1,5):
    result.append(element)
print(result)  # [1, 2, 3, 4]

result = [element for element in range(1,5)] 
print(result)  # [1, 2, 3, 4]
```

また、__if文__を入れることで__条件にマッチした要素のみ__収集する事が可能です。

```py:条件有りリスト内包表記
result = [element for element in range(1,5) if element % 2 == 0] 
print(result)  # [2, 4]
```

### 集合内包表記

以下は同じです。

```py:集合内包表記
result = set()  # {}だと辞書型だと思われるのでエラーが発生する
for element in range(1,5):
    result.add(element)
print(result)  # {1, 2, 3, 4}

result = {element for element in range(1,5)}
print(result)  # {1, 2, 3, 4}
```

(@shiracamus さんご指摘ありがとうございます！)

### 辞書内包表記

以下は同じです。

```py:辞書内包表記
result = {}
for element in range(1,5):
    result[str(element)] = element * element
print(result)  # {'4': 16, '3': 9, '1': 1, '2': 4}

result = {str(element): element * element for element in range(1,5)}
print(result)  # {'4': 16, '3': 9, '1': 1, '2': 4}
```

## 関数関連

### 定義の仕方

```py:関数定義
def add(x, y):
    result = x + y
    return(result)
    
print(add(1,3))  # 実行結果 -> 4
```

### ビルドイン関数

#### map

リストの__全ての要素__に__同様の処理__を行います。
ただ、__Python3系__ではmap関数は__mapオブジェクト__で返ってくるので、リストにする場合は__list関数__をかませる必要があります。

```py:Python
def sample(value):
    return value * value

print (resultList)
resultMap = map(sample, range(1,5))
print (resultMap)  # <map object at 0x101463518>

resultMap = map(sample, range(1,5))
resultList = list(resultMap)
print (resultList)  # [1, 4, 9, 16]
```
```java:Java
int [] result = IntStream.range(1, 5)
    .map( element -> element * element)
    .toArray();
String resultStr = Arrays.toString(result);
System.out.println(resultStr);  // [1, 4, 9, 16]
```

### ラムダ式

もちろん、Pythonでも__lambda式__を使うことは出来ます。
__前述のmap関数__をlambda式にすると以下のようになります。

```py:Python
resultMap = map(lambda element: element * element, range(1,5))
resultList = list(resultMap)
print (resultList)  # [1, 4, 9, 16]
```

## 文字列関連

### 結合

結合は「__+__」で可能です。
または、「__+=__」でも可能です。
「__*__」を使うことで__指定回数結合__を繰り返すことが出来ます。

```py:結合
name = "yamada"
kana = "ヤマダ"

print( name + ":" + kana )  # yamada:ヤマダ

name = "yamada"
name += ":"
name += "ヤマダ"

print( name )  # yamada:ヤマダ

name = "yamada" * 3
print( name )  # yamadayamadayamada
```

#### 配列の場合

配列を結合して一つの文字列にしたい場合は、join関数を使って

```
persons = ["Taro", "Jiro", "Hanako"]
personsStr = ' #'.join(persons)  # Taro,Jiro,Hanako
```

とすることが出来ます。


### 数値　→　　文字列

__数値を文字列化__するには「__str関数__」を使います。
そのまま実行してしまうと__<font color="red">エラー</font>__が出てしまいます。

```py:エラー
name = "yamada"
age = 20

print( name + ":" + age )  # Can't convert 'int' object to str implicitly
```
```py:正常
name = "yamada"
age = 20

print( name + ":" + str(age) )  # yamada:20
```

### 置換

__文字列の一部を置換__するには「__replace関数__」を使います。

```py:置換
name = "yamada"

print( name.replace("yama", "umi") )  # umida
```

### 分割

__文字列の分割__には「__split関数__」を使います。

```py:分割
name = "yamada:20"

print( name.split(":") )  # ['yamada', '20']
```

### 検索

__文字列検索__をする方法は複数あります。

#### 文頭

__文字列が指定の文字で始まっているか__を求めるには「__startswith関数__」を使います。

```py:文頭
name = "yamada"

print( name.startswith("yama") )  # True
print( name.startswith("umi") )  # False
```

#### 文中

__文字列の中に指定の文字が含まれている__かを求めるに「__in構文__」を使います。

```py:文中
name = "yamada"

print( "ya" in name  )  # True
print( "ma" in name  )  # True
print( "da" in name  )  # True
print( "umi" in name  )  # False
```

#### 文末

__文字列が指定の文字で終わっているか__を求めるには「__endswith関数__」を使います。

```py:文末

name = "yamada"

print( name.endswith("yama") )  # True
print( name.endswith("mada") )  # False
```