[Python入門] 覚えておくと得するかもしれない書き方集

# はじめに
この記事では今まで自分がPythonを勉強してきて、基本的なところながら便利だなあと思った書き方についてまとめてみます。
ターゲットとして**「最近Pythonの勉強を始めた」**くらいの方を想定しています。

# f記法
Python3.6以降では、`f"{変数名}"`とすることで、変数が展開されます。

```python
>>> fruit = "apple"
>>> drink = "coffee"

>>> print("I like " + fruit + " and " + drink + " very much.") 
I like apple and coffee very much.

>>> print("I like {fruit} and {drink} very much.".format(fruit=fruit, drink=drink)) 
I like apple and coffee very much.

# f記法を使うことで、直感的かつ簡単に記述することができます。
>>> print(f"I like {fruit} and {drink} very much.")
I like apple and coffee very much.
```

# 数式関連
数式を書いていると、横に長くなってしまい視認性が悪くなってしまうことがあります。
このような時は `\`を使うことで、**複数行に渡ってひとつの数式を記述**することができます。

```python
>>> a = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
>>> a
55

>>> a = 1 + 2 + 3 + 4 + 5 \ # 末尾に\をつける
...     + 6 + 7 + 8 + 9 + 10
>>> a
55
```

**2018/07/18 追記**
@shiracamus さんから`()`を使う方法をコメントでいただいたため、追記しました。`()`の中は改行・インデントルールが無視できるため、こちらの方が使い勝手が良さそうです。

```python
>>> a = (1 + 2 + 3 + 4 + 5 +
...      6 + 7 + 8 + 9 + 10)
... 
>>> a
55
```

# 文字列関連

### 同じ文字（列）を**繰り返し**

```python
>>> a = "a" * 10 
>>> a
'aaaaaaaaaa' # "a"を10個連結した文字列になる

>>> line = "-" * 50
>>> line
'--------------------------------------------------' # 区切り線なんかもこんな感じで作れる
```

### **末尾から**取り出す

```python
>>> str = "abcde"
>>> str[-1] # 末尾から1文字取り出す
'e'
```

### **逆順**にする

```python
>>> str = "abcde"
>>> str[::-1] # 文字を逆順にする
'edcba'
```
末尾、逆順についてはリストについても同じことができます。

### **2018/07/18 追記**
リストの繰り返しについても @Mco7777 さんからコメントをいただきました。少し応用的な内容になってしまいますが、ぜひご参照ください。

リストについても

```python
>>> a = [1] * 5
>>> a
[1, 1, 1, 1, 1]
```
このように繰り返しを使うことができます。ただしここでは、すべての要素が同一のidを持つことに注意してください。

```python
>>> for i in a:
...     print(id(i))
... 
4407293264
4407293264
4407293264
4407293264
4407293264
```

immutableなオブジェクト（文字列や数値など）を繰り返すときには基本的には気にする必要はありませんが、mutableなオブジェクト（リストなど）を繰り返す時には注意が必要です。

```python
>>> a = [[]] * 5
>>> a
[[], [], [], [], []]
>>> for i in a:
...     print(id(i))
... 
4415217608
4415217608
4415217608
4415217608
4415217608
# このように、すべての空リストが同一のidを持っている

>>> a[0].append(1)
>>> a
[[1], [1], [1], [1], [1]] # すべてのリストに1が追加されてしまう

```

このような状況は、のちにも説明がありますが**内包表記**を使うことで回避できます。

```python
>>> a = [[] for _ in range(5)]
>>> a
[[], [], [], [], []]
>>> for i in a:
...     print(id(i))
... 
4415222216
4415217352
4415217224
4415217032
4415217288
# すべての空のリストが各々別のidを持っている

>>> a[0].append(1)
>>> a
[[1], [], [], [], []] 
```

# リスト関連
### **リストの要素自身**をfor文で回す

```python
>>> fruits = ["apple", "orange", "banana", "peach", "melon"]

>>> for i in range(len(fruits)): 
...     print(fruits[i])
... 
apple
orange
banana
peach
melon
```
これはインデックスを使った書き方ですが、Pythonでは

```python
>>> fruits = ["apple", "orange", "banana", "peach", "melon"]

>>> for fruit in fruits: # fruitsの要素自体をfor文で回す
...     print(fruit)
... 
apple
orange
banana
peach
melon
```
のように書くことができます。

### **インデックス付き**で回す

`enumerate`を使用します。1つ目の変数がインデックスになることに注意してください。

```python
>>> for i, fruit in enumerate(fruits):
...     print(i, fruit)
... 
0 apple
1 orange
2 banana
3 peach
4 melon
```

### **リスト内包表記**

```python
>>> a = []

>>> for i in range(10):
...     a.append(i * 2)
... 
>>> a
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
```
これは、以下のようにリスト内包表記を使用することで1行で記述することができます。

```python
>>> a = [i * 2 for i in range(10)]
>>> a
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
```
# 辞書関連
### **valueの値で**辞書をソートする

自分は辞書を扱っていると`value`でソートしたい場面によく出くわしました。
ですが通常、辞書に対して単純にソートを行うと`key`でソートされます。

```python
>>> d = {"a": 1, "d": 3, "e": 4, "c": 2, "b": 5}

>>> dict(sorted(d.items()))
{'a': 1, 'b': 5, 'c': 2, 'd': 3, 'e': 4} # key がアルファベットの昇順にソートされた
```

ここで、`lambda`を用いた次のような書き方をすることで、`value`の値で辞書をソートすることができます。

```python
>>> d = {"a": 1, "d": 3, "e": 4, "c": 2, "b": 5}

>>> dict(sorted(d.items(), key=lambda x: x[1]))
{'a': 1, 'c': 2, 'd': 3, 'e': 4, 'b': 5} # value が数値の昇順にソートされた
```

また、`reverse=True`を指定することで、降順に並べることもできます。

```python
>>> d = {"a": 1, "d": 3, "e": 4, "c": 2, "b": 5}

>>> dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
{'b': 5, 'e': 4, 'd': 3, 'c': 2, 'a': 1} # value が数値の降順にソートされた
```
ちなみにここでは、要素としてタプルを持っているリストは一発で辞書型に変換することができるという性質も利用しています。

```python
>>> a = [('a', 1), ('b', 5), ('c', 2), ('d', 3), ('e', 4)]
>>> b = dict(a) # dict型にキャストする
>>> b
{'a': 1, 'b': 5, 'c': 2, 'd': 3, 'e': 4}
```
### **辞書内包表記**

辞書においても、リストと同様に内包表記を使用することができます。

```python
>>> fruits = ["apple", "orange", "banana", "beach", "melon"]
>>> a = {}

>>> for i, fruit in enumerate(fruits):
...     a[fruit] = i
... 
>>> a
{'apple': 0, 'banana': 1, 'beach': 2, 'orange': 3, 'melon': 4}
```
これを

```python
>>> fruits = ["apple", "orange", "banana", "beach", "melon"]

>>> {fruit: i for i, fruit in enumerate(fruits)}
{'apple': 0, 'banana': 1, 'beach': 2, 'orange': 3, 'melon': 4}
```
のように書くことができます。

### 2018/7/18 追記
ソートした辞書をそれ以降も使用したい場合には`OrderedDict`を使用します。Pythonのdict型は順序を保存しないため、使用するたびに毎回ソートしなければならなくなってしまいます。（@Hoge42 さんコメントありがとうございました！）

```python
>>> from collections import OrderedDict
>>> d = {"a": 1, "d": 3, "e": 4, "c": 2, "b": 5}
>>> OrderedDict(sorted(d.items()))
OrderedDict([('a', 1), ('b', 5), ('c', 2), ('d', 3), ('e', 4)])
# OrderdDictを使用することで、順序が保存され今後ソートし直さなければならなくなるといったような状況を回避できます
```
ちなみに、**Python3.7からはdict型でも順序が保存**されるようになるらしいです、便利。

# おわりに
以上になります。本記事ではこのように基本的でありながら、知っていると便利なことをいくつかまとめてみました。
もちろんこれで全てを網羅できているということはありませんが、本記事が少しでもこれからPythonを勉強していく方々の参考になると幸いです。
ここまで読んでいただきどうもありがとうございました！