サブロウ丸

Sabrou-mal サブロウ丸

主にプログラミングと数学

Python ショートコーディング Tips

Pythonはcやjavaよりも可読性が優れている言語です。 その可読性を十分に発揮する、つまり人が見て読みやすいプログラムにするには、プログラムにある程度冗長性を持たせる必要があります。

基本的には短いプログラムほど理解しやすいですが、技巧的に短くしすぎると逆に可読性が失われてしまうからです。 しかしそのデメリットを無視しても、できるだけ短く書きたいときもあるでしょう。

僕がこれまで培ってきたもの(自分で考えたものや、他人のプログラムでこれは!と感心したもの)の中で、技巧的に短く書ける例を挙げていきたいと思います。 なお全てpython3.6を想定して書いておりますのでご了承ください。

if -> list

pythonでは真偽値Falseは0, Trueは1として扱われます。 この性質を利用して, listの引数として真偽値を用いることが可能です。

if a == 10:
    print('OK')
else:
    print('NG')

例えば上のif文については

print(['NG', 'OK'][a == 10])

と書くことができます。もし a == 10ならばprint(['NG', 'OK'][1])と同値になりOKが出力されます。 もし not a == 10ならば print(['NG', 'OK'][0])と同値になりNGが出力されます。

少し応用すると

if a == 10 and b == 10:
    print('both')
elif a != 10 and b != 10:
    print('neither')
else:
   print('either')

print(['neither', 'either', 'both'][(a == 10) + (b == 10)]

と書くことができます。

input()あれこれ

a = int(input())
b = int(input())
c = int(input())

i = input
a = int(i())
b = int(i())
c = int(i())

関数も変数として扱える性質を使っています。 これはさらにラムダ式を使うと

j = lambda : int(input())
a = j()
b = j()
c = j()

と書くことも可能です。

a,b=map(int,input().split())
x,y=map(int,input().split())

a,b,x,y=map(int,(input()+" "+input()).split())

空白付きで文字列を結合してsplitしています。

t=list(map(int,input().split(' ')))
print('OK') if t[3] or t[0]+t[1]+t[2]<2 else print('NG')

*a,b=map(int,input().split())
print(['NG', 'OK'][sum(a)<2 or b])

この代入方法は面白く、以下のようなこともできます。

a = [1, 2, 3, 4]
*b, c = a    # -> b = [1, 2, 3], c = 4
*b, c, d = a # -> b = [1, 2], c = 3, d = 4
b, *c = a    # -> b = 1, c = [2, 3, 4]
b, *c, d = a # -> b = 1, c = [2, 3], d = 4

range

細かい話になります。

for i in range(10):
     ...

for文を用いる場合そのネスト(for文の中身)でiというイテレーターを使っていない場合は、以下のように書くことができます。

for i in '1'*10:
    ...

'1'*10で'1'が10個連なった、'1111111111'という文字列が生成されます。文字列に対してfor文を回すので、iに'1'が10回代入されるような挙動になります。

この書き方で字数を3文字ほど削減することができますね(細かい)。

細々

from math import sqrt
m = sqrt(n)

m = n**0.5

知ってたら何のことはないですね。

最後に, かなり限定的ですが リストで作成した行列を右に90度回転させるとき

M = [[0 for i in range(100)] for i in range(100)]
M = [x[::-1] for x in zip(*M)]

とかけます(適用例: leetcode:48. Rotate Image)

実際に試してみてください。