1

下記のようなlistがあります。

list = [16, 1, 9, 26, 1]

これを、隣り合う二つの要素を加算していくロジックを組みたいのですが、上手く組めずにいます。
最終的にlist内が1つになったら終了します。
分かる方がいらっしゃいましたらご教示よろしくお願いいたします。

目的の出力

[16, 1, 9, 26, 1]→[17, 10, 35, 27]→[27, 45, 62]→[72, 107]→[179]
# 最終出力結果
179

こんな感じの出力結果を出したいです。
よろしくお願いいたします。

cubick
  • 20,987
  • 5
  • 25
  • 64
hideto.T
  • 105
  • 1
  • 6

3 Answers3

2

最終的にlist内が1つになったら終了します。

[16, 1, 9, 26, 1]→[17, 10, 35, 27]→[27, 45, 62]→[72, 107]→[179]
# 最終出力結果
179

上記の通りに処理を行う場合は以下。

from functools import reduce

lst = [16, 1, 9, 26, 1] result = reduce(lambda s, _: list(map(sum, zip(s, s[1:]))) or s[0], lst, lst) print(result)

179

補遺

憶測になりますが、これは二項係数を使って解く事が期待されている課題なのではないかと思います。

[a1, a2, a3, a4, a5]
=>
[(a1+a2), (a2+a3), (a3+a4), (a4+a5)]
=>
[(a1+2*a2+a3), (a2+2*a3+a4), (a3+2*a4+a5)]
=>
[(a1+3*a2+3*a3+a4), (a2+3*a3+3*+a5)]
=>
[a1 + 4*a2 + 6*a3 + 4*a4 + a5]
from math import factorial as fc, comb

lst = [16, 1, 9, 26, 1] n = len(lst) - 1 binomial_coefficients = [comb(n, n-r) for r in range(n+1)] print(sum(x*y for x, y in zip(binomial_coefficients, lst)))

179

metropolis
  • 6,535
  • 2
  • 5
  • 15
  • コメントありがとうございます。ちょっとロジックが難しいですが 頑張って理解します。 – hideto.T Nov 21 '21 at 07:55
  • 補足コメントありがとうございます。二項係数ですか。再度公式を観ながら理解を深めます。いろいろと教えてくださりありがとうございます。 – hideto.T Nov 21 '21 at 08:52
2

別解です。

>>> tmp = [16, 1, 9, 26, 1]
>>> while len(tmp) > 1:
...     tmp = [i+j for i,j in zip(tmp, tmp[1:])]
...
>>> tmp.pop()
179

Pythonでリスト1個ずらしのループは以下の方法がよく使われます。

>>> L = [16, 1, 9, 26, 1]
>>> for i,j in zip(L, L[1:]):
...     print(i+j)
...
17
10
35
27

これを内包表記にします

>>> tmp = [i+j for i,j in zip(L, L[1:])]
>>> tmp
[17, 10, 35, 27]

これを繰り返し実行します

>>> tmp = [i+j for i,j in zip(tmp, tmp[1:])]
>>> tmp
[27, 45, 62]
>>> tmp = [i+j for i,j in zip(tmp, tmp[1:])]
>>> tmp
[72, 107]
>>> tmp = [i+j for i,j in zip(tmp, tmp[1:])]
>>> tmp
[179]

繰り返しは最後1個になるまで行うので、whileで書きます

>>> tmp = L
>>> tmp
[16, 1, 9, 26, 1]
>>> while len(tmp) > 1:
...     tmp = [i+j for i,j in zip(tmp, tmp[1:])]
...
>>> tmp
[179]
Takayuki SHIMIZUKAWA
  • 5,779
  • 12
  • 18
1

素直に書いてあるロジックどおりの実装をしました。

L = [16, 1, 9, 26, 1]
while len(L) > 1:
    L = [num + L[i+1] for i, num in enumerate(L[:-1])] #末尾の1つ前の要素まで
    print(L)
print(L[0])

出力結果

[17, 10, 35, 27]
[27, 45, 62]
[72, 107]
[179]
179

内包表記をつかわないとしたらこんな感じです。

L = [16, 1, 9, 26, 1]

while len(L) > 1: tempL = [] for i, num in enumerate(L[:-1]): tempL.append(num + L[i+1]) L = tempL print(L)

print(L[0])

civi
  • 361
  • 1
  • 7
  • コメントありがとうございます。このようなやり方があるんですね。 とても勉強になります。ありがとうございます。 – hideto.T Nov 22 '21 at 14:01
  • すみません。こちらを内包表記以外で実装する方法はありますか? いろんな手順を覚えたいためです。

    ちなみに、下記のコードで実装しましたがうまく行きませんでした。

    L = [16, 1, 9, 26, 1] index = 0 result_list = [] while index < len(L): for i, num in enumerate(L[:-1]): result = num + L[i+1] result_list.append(result) index += 1 print(result_list)

    – hideto.T Nov 22 '21 at 16:13
  • 内包表記を使わないやり方についても回答に追記しました。 – civi Nov 23 '21 at 13:30
  • コメントありがとうございます。自分のと何が違うか比較して学習します。 ありがとうございます。 – hideto.T Nov 24 '21 at 14:00