標準入力から3個の整数を読んで・・・

「標準入力から3個の整数を読んでその和を出力するプログラムを作れ」という問題がありました。もともとは AtCoder のサンプル問題(の一部)で,区切りのスペースや改行の入り方が指定されていたのですが,ここでは区切りは任意の空白文字(スペース,タブ,改行)とします。

C言語なら

#include <stdio.h>

int main(void)
{
    int a, b, c;

    scanf("%d%d%d", &a, &b, &c);
    printf("%d\n", a + b + c);
    return 0;
}

でどんな空白文字がどんな順番で現れても大丈夫ですが,Pythonで input() を使うと1行ごとに戻ってきてしまうので,フォーマットが固定されていないと,けっこう難しい問題になりそうです。ところが,Twitter でいろいろお教えいただいて,sys.stdin.read().split で簡単にできることがわかりました。

import sys

print(sum(int(s) for s in sys.stdin.read().split()))

同じことを map() を使って書くと

import sys

print(sum(map(int, sys.stdin.read().split())))

となって,エレガントですが,どういうわけか Pythonista たちは for のほうを好むという話があるようです。

a = ['123', '234', '345', '456', '567', '678', '789']

%timeit sum(int(x) for x in a)
2.34 µs ± 189 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit sum(map(int, a))
1.54 µs ± 59.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

この場合は若干 map() のほうが速そうです。

なお,実際は,標準入力を全部読むのではなく,頭の1000文字分くらいで十分でしょうから,read(1000) などとするほうが安全ですね。


[2022-08-17 追記] 最近出た『アルゴリズム的思考力が身につく! プログラミングコンテストAtCoder入門』という本では,入力例として同じ行に二つの整数が並んでいるような場合,

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

という書き方が多用されているようです。