1. lethe2211

    No comment

    lethe2211
Changes in body
Source | HTML | Preview
@@ -1,207 +1,207 @@
-[Pythonで競技プログラミングする時に知っておきたいtips](http://qiita.com/lethe2211/items/b91cc9e2b355ad32f1e6)の,制御構造についての部分を分割しました.
+[Python2で競技プログラミングする時に知っておきたいtips](http://qiita.com/lethe2211/items/b91cc9e2b355ad32f1e6)の,制御構造についての部分を分割しました.
Pythonのバージョンは2.7.5(Python3では,入出力などの仕様が大きく異なるので,他の記事を参照することをおすすめします).
## 条件分岐
### 条件式に変数を渡す
個人的にはあまり好きではないが,コード量削減のために,
```python
while 1:
a = input()
if not a:
break
# ...
```
みたいに,if文,while文などの条件に変数を渡すことが多い気がする.
[PythonでIf文に変数を入れたときの結果 - LIFE WITH PYTHON](http://www.lifewithpython.com/2013/02/python-if-statement-data-type.html)
| 型 | 結果 |
|:---------:|------------|
| int | 0ならFalse,それ以外ならTrue |
| float | 0.0ならFalse,それ以外ならTrue |
| str | ''(空文字)ならFalse,それ以外ならTrue |
| list | []ならFalse,それ以外ならTrue |
| tuple | ()ならFalse,それ以外ならTrue |
| dict | {}ならFalse,それ以外ならTrue |
| set | set()ならFalse,それ以外ならTrue |
| None | False |
### 処理を途中で終了したい
入力の終わりを表す記号や,コーナーケースが入力された場合など,途中でスクリプトの実行を終了してしまった方が楽な場合がある.
このような場合は,`quit()`または`sys.exit()`を使うとよい.
```python
a = input()
if a == 0:
quit()
# ...
```
```python
import sys
a = input()
if a == 0:
sys.exit()
# ...
```
## 繰り返し
### range()とxrange()
[2. 組み込み関数 — Python 2.7ja1 documentation](http://docs.python.jp/2/library/functions.html)
Pythonで「○○をn回行う」と言った単純な繰り返しを実装する場合は,
```python
n = 5
for i in range(n):
print i
# 0
# 1
# 2
# 3
# 4
```
または,
```python
n = 5
for i in xrange(n):
print i
# 0
# 1
# 2
# 3
# 4
```
のように書くのが一般的.
ここで,`range(n)`,`xrange(n)`は,それぞれ,0からnまでの整数を昇順に並べたlistオブジェクト,xrangeオブジェクトを返す.
xrangeオブジェクトは,遅延評価を用いることで,値が必要とされるときに取り出すことの出来るオブジェクト.
nが非常に多くなる場合,`range(n)`ではリストを生成してからループを行うため,メモリ使用量が大きくなってしまうが,`xrange(n)`ではそれが避けられる.
また,速度についても,一部の場合を除いて`xrange()`の方が高速.
[python - Should you always favor xrange() over range()? - Stack Overflow]
(http://stackoverflow.com/questions/135041/should-you-always-favor-xrange-over-range)
また,(x)rangeでは,第2,第3引数を用いたり,`reversed()`を用いることで,いろいろな範囲の表現ができる.
```python
# range(start, stop)で,startからstop-1までの整数すべてを昇順に並べたリストを返す
print range(2, 6) # [2, 3, 4, 5]
# range(start, stop, step)で,startからstepおきに値を増やしていって得られる整数の内,stop-1までのすべてのものを昇順に並べたリストを返す
print range(5, 30, 5) # [5, 10, 15, 20, 25]
# reversed()でリストを逆順にできる
for i in reversed(range(5)):
print i
# 4
# 3
# 2
# 1
# 0
```
### for文での変数の展開
for文で,
```python
l = [1, 2, 3, 4, 5]
for e in l:
print e
```
```:output
1
2
3
4
5
```
のように,リストの各要素を展開できるが,これは,
```python
l = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
for i, e in l:
print '#{0}: #{1}'.format(i, e)
```
```:output
0: a
1: b
2: c
3: d
```
のようにもできる.
### enumerate
forループを回す際,リストのインデックスと値が同時に取得できるといい場合がある.
`enumerate()`は,引数のリストに対して,インデックスとその値を持つイテレータを返す.
```python
l = ['a', 'b', 'c', 'd']
for elem in enumerate(l):
print elem
# (0, 'a')
# (1, 'b')
# (2, 'c')
# (3, 'd')
# 上のコードは下記のコードと等価
for i in range(len(l)):
print (i, l[i])
```
### for-else,while-else文
Pythonでは,for文,while文にelse節を加えることができる.
この際,else節は,ループ終了までに一度も内部でbreakされなかった場合のみ呼び出される.
```python
a = [1, 2, 3, 4, 5]
b = [1, 2, 4, 5]
x = 3
def find_val(l, x):
for i in range(len(l)):
if l[i] == x:
print i
break
else:
print 'Not found...'
# 上のfind_val()と等価なコード
def find_val2(l, x):
flag = False
for i in range(len(l)):
if l[i] == x:
print i
flag = True
break
if not flag:
print 'Not found...'
find_val(a, x) # 2
find_val(b, x) # Not found...
```
「xを探せ.見つからなかった時は'hoge'を出力しろ」みたいな設問の際,フラグを持つ必要が無いため,非常に書きやすくて便利.
ただし,ループが多重になる場合はかえって見通しが悪くなるため,使わない方がよい.