lst = [fib(), trib(), ... dod()]として関数をリストに入れてしまえば、for文を使ってlstiのように書けるのではないかと思い試してみたのですが、リストに入れた関数はint扱いになる
それだと呼び出した結果がリストに格納されます。
呼び出さずに、関数オブジェクト自体を使ってやれば良いのです。
Python
1lst = [fib, trib, ..., dod]
追記
関数fib, trib, tetrなどの計算量が気になります。
functools.lru_cacheを利用するか、ジェネレータ関数として実装し直すことをお勧めします。
ランダムアクセスが必須なら前者、シーケンシャルアクセスで良いなら後者が良いでしょう。
書いてみた
面白そうだったので、個人的な趣味全開で書いてみました。
main.py
Python
1from fibonacci import gen_fibonacci_n
2from namedzip import NamedZip
3
4
5func_dct = dict(zip(
6 ['fib', 'trib', 'tetr'], map(gen_fibonacci_n, [2, 3, 4])
7))
8
9it = enumerate(NamedZip(**func_dct), start=1)
10for count, dct in it:
11 print('{:-^20s}'.format(f' count: {count:2d} '))
12 for name, val in dct.items():
13 print('{:6s} {:3d}'.format(f'{name}:', val))
14
15 print()
16
17 #
18 if dct['fib'] < dct['trib']:
19 break
fibonacci.py
Python
1import collections
2import itertools
3
4
5def gen_fibonacci_n(n: int):
6 sequence = collections.deque(
7 itertools.repeat(0, n-1)
8 )
9 sequence.append(1)
10
11 total = 1
12 while True:
13 yield sequence[0]
14
15 sequence.append(total)
16 total = 2 * total - sequence.popleft()
namedzip.py
Python
1class NamedZip:
2 def __init__(self, dct=None, **kwards):
3 if dct:
4 kwards = {**dct, **kwards}
5
6 self._names = kwards.keys()
7 self._iters = [
8 iter(val) for val in kwards.values()
9 ]
10
11 def __iter__(self):
12 return self
13
14 def __next__(self):
15 return dict(zip(
16 self._names, [next(it) for it in self._iters]
17 ))
実行結果 Wandbox
plain
1---- count: 1 -----
2fib: 0
3trib: 0
4tetr: 0
5
6---- count: 2 -----
7fib: 1
8trib: 0
9tetr: 0
10
11---- count: 3 -----
12fib: 1
13trib: 1
14tetr: 0
15
16---- count: 4 -----
17fib: 2
18trib: 1
19tetr: 1
20
21---- count: 5 -----
22fib: 3
23trib: 2
24tetr: 1
25
26---- count: 6 -----
27fib: 5
28trib: 4
29tetr: 2
30
31---- count: 7 -----
32fib: 8
33trib: 7
34tetr: 4
35
36---- count: 8 -----
37fib: 13
38trib: 13
39tetr: 8
40
41---- count: 9 -----
42fib: 21
43trib: 24
44tetr: 15
遠回りしている感が否めませんが、NamedZipは少し使いやすそう。
コメントを受けて
簡単な説明をコードに付け加えていただけると助かります。
デバッグプリントだけ加えておきました。
Python
1import collections
2import itertools
3
4
5def gen_fibonacci_n(n: int):
6 sequence = collections.deque(
7 itertools.repeat(0, n-1)
8 )
9 sequence.append(1)
10
11 total = 1
12 while True:
13 print(sequence)
14 yield sequence[0]
15
16 sequence.append(total)
17 total = 2 * total - sequence.popleft()
18
19
20print('{:-^20s}'.format('fibonacci'))
21gen_fib = gen_fibonacci_n(2)
22for e in itertools.islice(gen_fib, 10):
23 print(e)
24
25print('{:-^20s}'.format('tribonacci'))
26gen_trib = gen_fibonacci_n(3)
27for e in itertools.islice(gen_trib, 10):
28 print(e)
実行結果 Wandbox
plain
1-----fibonacci------
2deque([0, 1])
30
4deque([1, 1])
51
6deque([1, 2])
71
8deque([2, 3])
92
10deque([3, 5])
113
12deque([5, 8])
135
14deque([8, 13])
158
16deque([13, 21])
1713
18deque([21, 34])
1921
20deque([34, 55])
2134
22-----tribonacci-----
23deque([0, 0, 1])
240
25deque([0, 1, 1])
260
27deque([1, 1, 2])
281
29deque([1, 2, 4])
301
31deque([2, 4, 7])
322
33deque([4, 7, 13])
344
35deque([7, 13, 24])
367
37deque([13, 24, 44])
3813
39deque([24, 44, 81])
4024
41deque([44, 81, 149])
4244
dequeをn長のキューとして利用しています。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/05/06 10:49
退会済みユーザー
2019/05/06 18:05
2019/05/07 01:03 編集