ユーニックス総合研究所

  • home
  • archives
  • python-gokei

Pythonで合計を求める方法【sum, for文, オブジェクト, 辞書】

  • 作成日: 2023-07-04
  • 更新日: 2023-12-25
  • カテゴリ: Python

Pythonで合計を求める

この記事ではPython合計を求める方法を解説します。
具体的には以下の方法を見ていきます。

  • sum関数で合計を求める
  • for文で合計を求める

関連記事
Djangoでオブジェクトを一括作成・更新【bulk_create, bulk_update】
DjangoのModel.objects.filter()の使い方【QuerySet】
Djangoのmodelのcreate()の使い方【Python】
Django入門: ルートの設定 ~ 簡単な一行掲示板アプリを作る その4【Windows10】
NumPyのappend()の使い方: 配列の末尾に要素を追加
Numpyのarangeの使い方: 指定範囲の数列を生成する
Python3でYoutube Data APIを使ってキーワード検索する
PythonからC言語(my.puts)を呼び出して実行する

sum関数で合計を求める

Pythonでリストに入っている値の合計値を求めるには組み込みのsum関数を使います。

lis = [1, 2, 3, 4, 5]  
gokei = sum(lis)  
print(gokei)  
# 15  

上記の場合、リストはlisになります。
このlisには1から5までの値が入っています。
このlissum関数に渡すと合計値(gokei)が求まり返ってきます。

sum関数はタプルに対しても使えます。

lis = (1, 2, 3, 4, 5)  
gokei = sum(lis)  
print(gokei)  
# 15  

またジェネレーターに対しても有効です。

def gen():  
    for i in range(1, 6):  
        yield i  

g = gen()  
gokei = sum(g)  
print(gokei)  
# 15  

sum関数はリストなどの中に計算できない値が含まれている場合はTypeErrorを返します。

lis = [1, None, 3, 4, 5]  
gokei = sum(lis)  
# TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'  

上記の場合、リストの中にNoneが含まれていますが、Noneは加算できないのでこのようなエラーになります。

またsum関数の第2引数にはstartを設定できます。これは結果に上乗せする値です。
たとえば

lis = [1, 2, 3, 4, 5]  
gokei = sum(lis, 10)  
print(gokei)  
# 25  

上記ではsum関数の第2引数に10を指定しています。
リスト[1, 2, 3, 4, 5]の合計値は15ですが、これに10が上乗せされて結果は25になります。
また第2引数のstartはPython3.8からキーワード引数としても使えるようになりました。

lis = [1, 2, 3, 4, 5]  
gokei = sum(lis, start=10)  
print(gokei)  
# 25  

for文で合計を求める

for文でリストなどの合計値を求めるには以下のようなコードを書きます。

lis = [1, 2, 3, 4, 5]  
gokei = 0  

for n in lis:  
    gokei += n  

print(gokei)  

for文 vs sum

for文の合計値算出とsum関数による合計値算出はどっちの方が速いのでしょうか?
ちょっと比べてみたいと思います。

import time  

lis = list(range(10000000))  

# for  

start = time.time()  

gokei = 0  
for n in lis:  
    gokei += n  

end = time.time()  
dif = end - start  
print(dif)  
# 0.6475639343261719  

# sum  

start = time.time()  
gokei = sum(lis)  
end = time.time()  
dif = end - start  
print(dif)  
# 0.19449114799499512  

筆者の環境ではかなり大きな差が出ました。
計測では圧倒的にsum関数の方が速い結果になりました。
できるだけsum関数を使った方が良いですね。

オブジェクトの特定の属性の合計値を求める

自作クラスなどを作ってオブジェクトに特定の属性を持たせます。
そして複数のオブジェクトのその属性の合計値を求める場合です。
愚直にfor文で求めるには以下のようなコードを書きます。

class Animal:  
    def __init__(self):  
        self.age = 20  


lis = [Animal(), Animal(), Animal()]  
gokei = 0  

for animal in lis:  
    gokei += animal.age  

print(gokei)  
# 60  

あるいはself.ageの値を抽出すればsum関数も使えます。

class Animal:  
    def __init__(self):  
        self.age = 20  


lis = [Animal(), Animal(), Animal()]  
lis = [animal.age for animal in lis]  
gokei = sum(lis)  
print(gokei)  
# 60  

辞書の合計値を求める

辞書の合計値を求めるにはdict.values()などと併用します。

d = { 'a': 1, 'b': 2, 'c': 3 }  
gokei = sum(d.values())  
print(gokei)  
# 6  

ditc.values()は辞書の値を集める関数です。
これの結果をsum関数に渡せば合計値が求まります。

マルチスレッド環境での合計値を求める

マルチスレッドを使って合計値を求めたい場合は以下のようなコードが考えられます。

from threading import Thread  

gokei = 0  

def worker():  
    global gokei  
    for i in range(1, 11):  
        gokei += i  

th1 = Thread(target=worker)  
th2 = Thread(target=worker)  
th1.start()  
th2.start()  
th1.join()  
th2.join()  

print(gokei)  
# 110  

ちなみにこの処理では排他的制御をしていませんが、心配な人はLockなどを使って排他的制御をされるといいでしょう。

from threading import Thread  
from threading import Lock  

gokei = 0  
gokei_lock = Lock()  

def worker():  
    global gokei, gokei_lock  
    for i in range(1, 11):  
        with gokei_lock:  
            gokei += i  

th1 = Thread(target=worker)  
th2 = Thread(target=worker)  
th1.start()  
th2.start()  
th1.join()  
th2.join()  

print(gokei)  
# 110  

と言ってもこの程度の合計を求める処理では排他的制御は必要ないかもしれません。
gokeiを使って別の計算等をする場合は排他的制御も必要ですがgokeiに加算しているだけなので、排他的制御をする意味もなさそうです。

おわりに

今回はPythonで合計を求める方法を解説しました。
なにか参考になれば幸いです。

🦝 < 合計値を算出

🦝 < sum関数!