Pythonを始めた時のメモ

#はじめに
数年前にpythonを触り始めた時のメモをまとめた備忘録です。
※今思うとこの数年でたくさんのことを知ることができて嬉しいです。


#順不同に色々

##Pythonを簡単に

pythonはインタープリタ言語で、コンパイルやリンクが必要出ないため、短時間でコーディングできる。対話的に(jupyter)利用することもでき、簡単な関数テストもできる。C言語との拡張も可能

##引数

スクリプトと引数は、変数sys.argvとして渡される。引数がない時は、sys.argv[0]には起動時スクリプト名が渡される。-cコマンドの形式では、argv[0]は`'-c'`となり、-mモジュールの時は、argv[0]は、モジュールのファイル名となる。


##環境変数設定

pythonを起動する際に、毎度同じコマンドを打つのが面倒なときに**環境変数PYTHONSTARTUP**に、起動時の実行コマンドを記載したファイルを指定することで、実行が可能。対話型のみで有効なのは注意。

##複数の変数へ代入できる

```python
>>> a = b = c = 123
>>> a
123
>>> b
123
>>> c
123
>>> 
```

##複数の型の混合した計算

intはfloatに変換される

```python
>>> 3*2
6
>>> 3*2.0
6.0
>>> 3.0*2.0
6.0
>>> 
```

##複素数

虚数は「j」または「J」で表す
complex(実部,虚部)の関数でも作れる。

```python
>>> 3j*3j
(-9+0j)
>>> 3j*complex(0,3)
(-9+0j)
>>> 3.0j*complex(0,3.0)
(-9+0j)
>>> 
```
複素数は常に実部、虚部が浮動小数点数で表される。
.realと.imagで取り出すことができる。

```python
>>> a = 2+3J
>>> a.real
2.0
>>> a.imag
3.0
>>> 
```
複素数は実数に変化する正しい方法が存在しないため、int()やfloat()での変換はできない。
大きさを求める場合には、abs()が利用できる。一応計算式も。

```python
>>> a = 2+3J
>>> a.real
2.0
>>> a.imag
3.0
>>> float(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float
>>>
>>> abs(a)
3.605551275463989
>>>
>>> import math
>>> math.sqrt(a.real**2+a.imag**2)
3.605551275463989
```

##アンダースコア

最後に計算された式は、アンダースコアに代入されている。

```python
>>> 3+2
5
>>> 3+_
8
```
##文字列結合

当たり前の結合。注目すべきはシングルクオートであること。

```python
>>> a = "hello"
>>> b = "world"
>>> a+b
'helloworld'
```
文字列の中に、シングルクオートが含まれていると、最後がダブルクオートになる。

```python
>>> c = "I've said "
>>> c+a+b
"I've said helloworld"
```
print()を使うとクオートが無くなる。

```python
>>> print(c+a+b)
I've said helloworld
```

並列で置くだけでも結合される

```python
>>> "hello" "world"
'helloworld'
```
あくまでリテラル同士であることが大事

```python
>>> "hello".strip() "world"
  File "<stdin>", line 1
    "hello".strip() "world"
                          ^
SyntaxError: invalid syntax
```
こういう時は演算子使う

```python
>>> "hello".strip()+"world"
'helloworld'
```
##スライスを作る

基本はこれ。

```python
>>> a = "Helloworld"
>>> len(a)
10
>>> a[0]
'H'
>>> a[1]
'e'
>>> a[5]
'w'
>>> a[9]
'd'
```
負の数だとこう。

```python
>>> a[-1]
'd'
>>> a[-1:]
'd'
>>> a[-5:]
'world'
```
注意が必要なのは「0」と「−0」。全く同じです。

```python
>>> a[0]
'H'
>>>
>>> a[-0]
'H'
```

スライスを作るときの考え方も簡単

```
 +---+---+---+---+---+---+
 | H | e | l | l | o | w |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1
```

スライスは第一のデフォルトが0で、第二が文字列のサイズになっています。
不適切なものが入ると空文字列が返ってきます。

```python
>>> a[0:3]
'Hel'
>>> a[3:]
'loworld'
>>> a[:100]
'Helloworld'
>>> a[5:1]
''
>>> a[-1:-5]
''
>>> a[10:]
''
>>> a[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range
```

C言語とは異なり、文字列は変更不能です。新しい文字列を生成することで同じようにできます。

```python
>>> a[:4]="goodmorning"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>>
>>> "goodmorning"+a[5:]
'goodmorningworld'
```

##リストの操作

リストは[,]角括弧のカンマ区切りで、変更が可能です。型は同じでなくても問題ありません。

pop()やremove()やcopy()を使わない操作

```python
>>> a=["hiro","yuki",33,[175,"80kg"]]
>>> a
['hiro', 'yuki', 33, [175, '80kg']]
>>>
>>> a[0:2]
['hiro', 'yuki']
>>> a[0:2] = []
>>> a
[33, [175, '80kg']]
>>> a[0] = "hiro"
>>> a
['hiro', [175, '80kg']]
>>> a[1:1]="yuki"
>>> a
['hiro', 'y', 'u', 'k', 'i', [175, '80kg']]
>>> a[1]="yuki"
>>> a
['hiro', 'yuki', 'u', 'k', 'i', [175, '80kg']]
>>> a[:0]=a
>>> a
['hiro', 'y', 'u', 'k', 'i', 'yuki', 'u', 'k', 'i', [175, '80kg'], 'hiro', 'y', 'u', 'k', 'i', 'yuki', 'u', 'k', 'i', [175, '80kg']]
```

##forやwhileの中でのリスト

反復対象のシーケンスを、ループの中で変更を加えるときには、リストのスライスコピーを作る必要がある。

以下では、無限ループがおきます。

```python
>>> a = ["bbb","ccccc","ddddddd","eeeeeeeee"]
>>> for x in a:
...     if len(x)>6:
...             a.insert(0,x)
>>>
```
スライスコピーすれば、元のリストは安全です。

```python
>>> a = ["bbb","ccccc","ddddddd","eeeeeeeee"]
>>> for x in a[:]:
...     if len(x)>6:
...             a.insert(0,x)
>>>
```
##range()について

終端値がリストに入らないのは周知ですね。
他の記事も書きましたが、出力の仕方が大事です。

```python

>>> range(10)
range(0, 10)
>>> print(range(10))
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(0,10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(0,10,2))
[0, 2, 4, 6, 8]
```

##関数の実行と参照について

関数が実行されると、関数内のローカルのシンボリックリンクに格納されます。
変数の参照は
・ローカルのシンボリックリンク
・グローバルのシンボリックリック
・ビルトインのシンボリックリンク
を調べるようになっています。

そのため関数内では、グローバル変数は,グローバル文を使わない限りは、参照しかできないようになっています。

また関数のデフォルト値は、関数を定義した時点で定義を行なっているスコープで評価されます。


##キーワード引数について

```python
>>> def intro(name,age = 33,weight = 80,height = 175):
...     print("my name is",name)
...     print("my age is",age)
...     print("my weight is",weight)
...     print("my height is",height)
... 
>>> intro("hiro")
my name is hiro
my age is 33
my weight is 80
my height is 175

>>> intro(name = "hiro",age = 35)
my name is hiro
my age is 35
my weight is 80
my height is 175
```
引数が足りないと以下のようになる

```python
>>> intro()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: intro() missing 1 required positional argument: 'name'

>>> intro(age = 33)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: intro() missing 1 required positional argument: 'name'
```
引数の重複やキーワード引数の後にキーワードでないものを置いた場合、定義されていないキーワード。
要は
**引数のリストでは、位置指定型引数を先に、キーワード引数を後に、コール時には仮引数を使う**
必要がある


```python
>>> intro("hiro",name = "yuki")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: intro() got multiple values for argument 'name'

>>> intro(name = "hiro",35)
  File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument

>>> intro(name = "hiro","yuki")
  File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument

>>> intro(area = "chiba")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: intro() got an unexpected keyword argument 'area'
```

##ドキュメンテーション文字列(docstirng)

・一行目にオブジェクトの目的を簡潔に書く
・大文字始まりで、ピリオド終わり
・複数行の場合は２行目は空行

##リストの操作

list.remove(x):xである**最初のアイテム**を削除する。該当がなければエラー
list.pop(i):指定された位置のアイテムをリストから削除し。消したアイテムを返す。位置が指定されない時は、最後のアイテムを削除する。
list.sort():インプレース(元のリストのコピーを取らずに)でソートします。reverse()は逆順。
del list[i]:pop()と似ているがスライスを使えるところが便利。値は返さない。

##シーケンスのアンパッキング

シーケンスと同等の長さの変数のリストがあればOK

```python
>>> a = ("a","b","c")
>>> a
('a', 'b', 'c')
>>> x,y,z = a
>>> x
'a'
```
keyvalueペアになっているタプルからなるリストは辞書に簡単に変換できる。

```
>>> a
[('A', 1), ('B', 2), ('C', 3)]
>>> dict(a)
{'A': 1, 'B': 2, 'C': 3}
```

zip()を使えば、forループを使うときに、簡単にペアにできる

```python
>>> a = ["a","b","c"]
>>> b = ["x","y","z"]
>>> for i,v in zip(a,b):
...     print(i+"と"+v+"はセット")
... 
aとxはセット
bとyはセット
cとzはセット
```
reversed（）やsorted()を使うと簡単に順番を変えられる。

```python
>>> for i,v in zip(a,reversed(b)):
...     print(i+"と"+v+"はセット")
... 
aとzはセット
bとyはセット
cとxはセット
```

#条件についてmemo

inとnot inははシーエンスに存在するかどうかのチェック
isとnot isは完全に同一であるかどうか

```python
>>> a = ["a","b","c"]
>>> a
['a', 'b', 'c']
>>> b = a
>>> b
['a', 'b', 'c']
>>> a == b
True
>>> a is b
True
>>> c = a.copy()
>>> c
['a', 'b', 'c']
>>> c == a
True
>>> c == b
True
>>> c is a
False
>>> c is b
False
```

比較演算子は連結できる

aがbより小さく、**かつ**bがcに等しい

```python
a < b == c
```

ブール演算子は、比較演算子よりも優先順位は低いことは、とても重要。
ブール演算子の中では、not>and>orの順位になります。

以下では　　　「aでありbではないもの」もしくは「c」であるもの

```python
a and not b or c
```

#オブジェクトの比較

```python
>>> 0 == 0.0
True
>>> 0 is 0.0
False
```

#一旦ここまで

メモはまだ1/5くらい、また更新します。