Pythonでリスト内のすべてのアイテムを乗算するにはどうすればよいですか?


204

数値のリストを受け取り、それらを乗算する関数を作成する必要があります。例: [1,2,3,4,5,6]私にくれ1*2*3*4*5*6ます。私は本当にあなたの助けを使うことができました。

回答:


208

Python 3:使用functools.reduce

>>> from functools import reduce
>>> reduce(lambda x, y: x*y, [1,2,3,4,5,6])
720

Python 2:使用reduce

>>> reduce(lambda x, y: x*y, [1,2,3,4,5,6])
720

2および3との互換性のためにpip install six、を使用します。

>>> from six.moves import reduce
>>> reduce(lambda x, y: x*y, [1,2,3,4,5,6])
720

演算子をインポートしないので、このソリューションはもう少しコンパクトです。どっちが速いのかな。
jheld 2014

30
@jheld:私は1から100までの数値の積を計りました。python2と3の両方でlambda、平均.02s / 1000回の繰り返しをoperator.mulとりましたが、平均.009s / 1000繰り返しを取り、operator.mul桁違いに速くなりました。
2014年

4
一方@wordsforthewiseは、おそらくそれは、余分な機能(ラムダ)を通過すると、オーバーヘッド追加していることだoperator.mulC.へ直進
whereswalden

4
私は本当に.009を.02より1桁低いとは呼びません。半分くらいです。
jlh

1
Python 3.8以降では、で簡単に実行できますmath.prod([1,2,3,4,5,6])。(コースのインポートが必要)
Tomerikoo

168

以下を使用できます。

import operator
import functools
functools.reduce(operator.mul, [1,2,3,4,5,6], 1)

説明については、reduceおよびoperator.mulドキュメントを参照してください。

import functoolsPython 3以降の行が必要です。


32
python3では、reduce()関数がグローバル名前空間から削除され、functoolsモジュールに配置されていることに注意してください。だからpython3ではあなたは言う必要がありますfrom functools import reduce
ユージーンヤーマッシュ2013年

2
3番目の引数としての「1」はここでは不要ですが、それが必要になるのはどのような場合ですか?
言葉の言い方については、

5
@wordsforthewise 3番目の引数がない場合、空のシーケンスを渡すとTypeError例外がスローされます
Francisco Couzo

1
lambda x,y: x*y次の代わりにも機能しますoperator.mul

79

を使用しnumpy.prodてタスクを実行します。下記参照。

import numpy as np
mylist = [1, 2, 3, 4, 5, 6] 
result = np.prod(np.array(mylist))  

13
すでにNumpyを使用している場合に便利です。おそらく最初にリストとしてキャストする必要すらありません。これはほとんどの場合に機能しますresult = np.prod(mylist)
Nick

4
注意するために2つのこと: 1)それは特に、デフォルトを使用している場合、オーバーフローする可能性があるnumpy.int32上記のように )2小さなリストではnumpyのがしばしば繰り返した場合、配列(関連を割り当てる必要があるので、これは、大幅に遅くなります)
幻滅

1
ここで21を超える値のオーバーフローnp.prod(np.array(range(1,21)))
PatrickT 2018年

それは良い選択ではありません。オーバーフローする可能性があり、遅くなります。試してくださいreduce
ペイマン

57

インポートを避け、Pythonのより複雑な領域を避けたい場合は、単純なforループを使用できます

product = 1  # Don't use 0 here, otherwise, you'll get zero 
             # because anything times zero will be zero.
list = [1, 2, 3]
for x in list:
    product *= x

7
細かい注意:Pythonのスライスは非常に簡単です。ここではプリミティブのみを扱っているため、list [0]で開始してlist [1:]を反復処理することで、1から開始するという小さな手間を回避できます。より機能的な「削減」の回答に慣れることは、他の状況でも役立つため、長期的には価値があります。
kungphu 2013年

@kungphu空の製品は通常1として定義されます。空のシーケンスを渡すと、ソリューションは代わりにIndexError例外をスローします
Francisco Couzo

@Francisco許可されていますが、空のシーケンスはこの関数の無効な入力であるため、この関数はおそらくその場合、何らかのフレーバーの例外をスローするはずです。実際、この関数は、2つ未満の値を持つシーケンスでは意味がありません。1つの値を持つシーケンスを渡して1を掛けると、基本的にそこにない値を追加したことになります。これは、予期しない動作に相当します。
kungphu 2016

1
@kungphu、この答えの動作は正しいです。つまり、長さ1のリストを渡すと値が返され、長さ0のリストを渡すと1が返されます。これは、sum([])を0または合計として与えるのと同じ考え方です([3])は3を参照として:en.wikipedia.org/wiki/Empty_product
emorris

数学関数についてのあなたのポイントがわかります。ただし、実際の開発状況では、入力を操作することを明示的に意図した関数が、入力ないか無効な入力に相当する値返すという非常にまれな状況と呼びます。それは演習の目的に依存すると思います。標準ライブラリを複製するだけの場合は、おそらく、言語が(または)言語がどのように実装されているか、またはどのように実装できるかについて人々に教えます。そうでなければ、有効な引数と無効な引数についてのレッスンを提供する良い機会を逃してしまうと思います。
kungphu

14

以降Python 3.8、標準ライブラリのモジュールに.prod関数が含まれていmathます。

math.prod(iterable, *, start=1)

このメソッドは、start値(デフォルト:1)と反復可能な数値の積を返します。

import math
math.prod([1, 2, 3, 4, 5, 6])

>>> 720

イテラブルが空の場合は、これが生成されます1(またはstart、指定されている場合は値)。


10

ここに私のマシンからのいくつかのパフォーマンス測定があります。これが長時間実行ループの小さな入力に対して実行される場合に関連します。

import functools, operator, timeit
import numpy as np

def multiply_numpy(iterable):
    return np.prod(np.array(iterable))

def multiply_functools(iterable):
    return functools.reduce(operator.mul, iterable)

def multiply_manual(iterable):
    prod = 1
    for x in iterable:
        prod *= x

    return prod

sizesToTest = [5, 10, 100, 1000, 10000, 100000]

for size in sizesToTest:
    data = [1] * size

    timerNumpy = timeit.Timer(lambda: multiply_numpy(data))
    timerFunctools = timeit.Timer(lambda: multiply_functools(data))
    timerManual = timeit.Timer(lambda: multiply_manual(data))

    repeats = int(5e6 / size)
    resultNumpy = timerNumpy.timeit(repeats)
    resultFunctools = timerFunctools.timeit(repeats)
    resultManual = timerManual.timeit(repeats)
    print(f'Input size: {size:>7d} Repeats: {repeats:>8d}    Numpy: {resultNumpy:.3f}, Functools: {resultFunctools:.3f}, Manual: {resultManual:.3f}')

結果:

Input size:       5 Repeats:  1000000    Numpy: 4.670, Functools: 0.586, Manual: 0.459
Input size:      10 Repeats:   500000    Numpy: 2.443, Functools: 0.401, Manual: 0.321
Input size:     100 Repeats:    50000    Numpy: 0.505, Functools: 0.220, Manual: 0.197
Input size:    1000 Repeats:     5000    Numpy: 0.303, Functools: 0.207, Manual: 0.185
Input size:   10000 Repeats:      500    Numpy: 0.265, Functools: 0.194, Manual: 0.187
Input size:  100000 Repeats:       50    Numpy: 0.266, Functools: 0.198, Manual: 0.185

Numpyは乗算が実行される前に配列を割り当てるため、小さい入力ではかなり遅いことがわかります。また、Numpyのオーバーフローにも注意してください。


好奇心から
脱出

私がいる疑いがあるmultiply_functoolsとは、multiply_numpy ルックアップすることによって圧迫されnpfunctoolsおよびoperator属性の検索に続いて、グローバルを。地元の人に切り替えてもらえませんか?_reduce=functools.reduce, _mul = operator.mul`(関数のシグネチャreturn _reduce(_mul, iterable)、本文など)
Martijn Pieters

1
また、numpyバージョンは最初に数値をnumpy配列に変換する必要があります。あなたは通常その変換を既に行っているでしょう、それをタイミングに含めることは本当に公平ではありません。リストをnumpy配列に一度変換すると、np.prod()オプションの開始は100要素以上で最速になります。
Martijn Pieters

8

個人的には、ジェネリックリストのすべての要素を一緒に乗算する関数が好きです。

def multiply(n):
    total = 1
    for i in range(0, len(n)):
        total *= n[i]
    print total

それはコンパクトで、単純なもの(変数とforループ)を使用し、私には直感的に感じます(問題をどのように考え、1つ取り、それを乗算し、次に次のように乗算するなど)。 )


3
素晴らしい、それは最もシンプルで最もわかりやすいです。
ghostkraviz 2017年

4
ではfor i in n:、なぜtotal *= iですか?それははるかに簡単ではないでしょうか?
Munim Munna

@MunimMunnaそれは私のために上記のように機能しませんでした。
athul

5

簡単な方法は次のとおりです。

import numpy as np
np.exp(np.log(your_array).sum())

10
ちょうど約何np.prod(your_Array)
dashesy

3

Numpy有するprod()リストの積を返す、またはそれのnumpyのので、この場合には、それは所与の軸上のアレイの製品の機能:

import numpy
a = [1,2,3,4,5,6]
b = numpy.prod(a)

...または、インポートするだけですnumpy.prod()

from numpy import prod
a = [1,2,3,4,5,6]
b = prod(a)

2

今日この質問を見つけましたNoneが、リストにが存在する場合がないことに気付きました。したがって、完全なソリューションは次のようになります。

from functools import reduce

a = [None, 1, 2, 3, None, 4]
print(reduce(lambda x, y: (x if x else 1) * (y if y else 1), a))

追加の場合、次のようになります。

print(reduce(lambda x, y: (x if x else 0) + (y if y else 0), a))

2
nums = str(tuple([1,2,3]))
mul_nums = nums.replace(',','*')
print(eval(mul_nums))

5
回答に説明を追加してください。回答方法
xenteros

3
私はコードを説明して説明しようとします:このコードは個人的にはあまり好きではありません。これはevalを使用するためです。これは文字列を引数または関数として解釈します(したがって、特に入力データを処理する場合は、一般的に安全ではないと見なされます) )。その前の行は、区切り記号で区切られたすべてのコンマを乗法*に置き換え、evalはこれを乗法として認識します。これのパフォーマンスは、特に他のソリューションと比較して
どうですか

うわー、そんな悪い考え!
コワルスキー

1

私はこれを次のようにしたいと思います:

    def product_list(p):
          total =1 #critical step works for all list
          for i in p:
             total=total*i # this will ensure that each elements are multiplied by itself
          return total
   print product_list([2,3,4,2]) #should print 48

1

これは私のコードです:

def product_list(list_of_numbers):
    xxx = 1
    for x in list_of_numbers:
        xxx = xxx*x
    return xxx

print(product_list([1,2,3,4]))

結果:( '1 * 1 * 2 * 3 * 4'、24)


0

再帰を使用するのはどうですか?

def multiply(lst):
    if len(lst) > 1:
        return multiply(lst[:-1])* lst[-1]
    else:
        return lst[0]


-1

'' 'ループのロジック使用を理解する唯一の簡単な方法' ''

Lap = [2,5,7,7,9] x = 1 for i in Lap:x = i * x print(x)


あなたの答えはこの質問の議論に新しいものを追加しません。
シド

-3

何もインポートしないのはとても簡単です。これは私のコードです。これは、リスト内のすべてのアイテムを乗算してそれらの積を返す関数を定義します。

def myfunc(lst):
    multi=1
    for product in lst:
        multi*=product
    return product

2
DeadChexの回答、piSHOCKの回答、Shakti Nandanの回答と重複しています。すでに提案されている回答を投稿しないでください。
Munim Munna

また、マルチを返す必要があります|-|
Lars
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.