すのふら

すのふら

日々の備忘録

アキュムレータについて調べる

Sparkの本読んでいて、アキュムレータというワードが出てきた。
あれ、これってCPUじゃないのと思っていろいろ調べたのでメモしておく。

CPUでアキュムレータっていうと算術論理演算装置(ALU)の演算結果を格納する場所ってイメージがあった。

wikipediaだと

アキュムレータ(英: Accumulator)は、コンピュータにおいて、演算装置による演算結果を累積する、すなわち総和を得るといったような計算に使うレジスタや変数のことである。

アキュムレータ (コンピュータ) - Wikipedia  
CPUだけじゃなくて、プログラムでも扱われるのね。知らんかった。

CPUで総和を得るって何ぞ?と思ったけど、 (計算する命令の場合になるが)アキュムレータに保持している値と、メモリに保持している値を計算して、アキュムレータの値を更新する。
その結果をメモリのどこかの番地に渡して、また計算するみたいな感じだと確かにその通りかなーと。

pythonでアキュムレータを確かめる

pythonでアキュムレータで総和を確かめてみようとすると、itertoolsのライブラリを使うことになる。

10.1. itertools — 効率的なループ実行のためのイテレータ生成関数 — Python 3.6.5 ドキュメント

ドキュメントを読む限り、加算できる型であればよいのでDecimalみたいな小数点や、Fractionみたいな分数の型でもOK
JSON読み込んだときみたいなstr型の場合はキャストしないと駄目なんだなー。

実際に動かす

バージョンはpython 3.5

import itertools
iter_ac = itertools.accumulate([1,2,3,4,5])

for i in iter_ac:
    print(i)

# 内包表記で書くとこれ
# result = [i for i in iter_ac]
# print(result)

結果

1
3
6
10
15

pythonでアキュムレータを確認してみると、前の計算結果と処理対象の値を加算しているというのが分かる。
 
1:1 + 0(前の計算結果がない=0だから)
2:2 + 1
3:3 + 3
4:4 + 6
5:5 + 10

itertools.accumulateの型

for文対応しているし、配列渡しているしListかな?と思ったけど

import itertools
iter_ac = itertools.accumulate([1,2,3,4,5])
print(type(iter_ac))

<class 'itertools.accumulate'>

イテレータってやつですな。思いっきりiterって書いているけどね……。
なので、for文で実行できるみたい。

[Python] 部屋とYシャツとイテレータとジェネレータと私 - くろのて

イテレータなので、ループで回さなくてもnext()で値は取れる。一応。

import itertools
iter_ac = itertools.accumulate([1,2,3,4,5])
print(type(iter_ac))

print(next(iter_ac))
print(next(iter_ac))
print(next(iter_ac))

1
3
6


next()後にループしたときの結果として、next()で出力されていない値がループの対象となる。

import itertools
iter_ac = itertools.accumulate([1,2,3,4,5])
print(type(iter_ac))

print(next(iter_ac))
print(next(iter_ac))
print(next(iter_ac))

print('ここからループ')
for i in iter_ac:
    print(i)

1
3
6
ここからループ
10
15