Bir listedeki tüm öğeleri Python ile nasıl çarpabilirim?


204

Ben bir sayı listesi alır ve birlikte çoğalır bir işlev yazmak gerekiyor . Örnek: [1,2,3,4,5,6]Bana verecek 1*2*3*4*5*6. Yardımını gerçekten kullanabilirim.

Yanıtlar:


208

Python 3: kullanın functools.reduce:

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

Python 2: kullanın reduce:

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

2 ve 3 kullanımı ile uyumlu pip install six, daha sonra:

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

Operatörü içe aktarmazsınız, bu nedenle bu çözüm biraz daha kompakttır. Hangisinin daha hızlı olduğunu merak ediyorum.
jheld

30
@jheld: Sayıları 1'den 100'e kadar zamanladım. Hem python2 hem de 3'te lambdaortalama .02s / 1000 tekrar operator.mulaldı, ortalama .009s / 1000 tekrar aldı ve operator.muldaha büyük bir sipariş daha hızlı oldu.
whereswalden

4
@wordsforthewise muhtemelen ekstra bir işlevden (lambda) operator.mul
geçmenin

4
Gerçekten .009'u .02'den küçük bir büyüklük sırası olarak adlandırmazdım. Yaklaşık yarısı.
JLH

1
Python 3.8'den itibaren, basitçe ile yapılabilir math.prod([1,2,3,4,5,6]). (elbette ithalat gerektirir)
Tomerikoo

168

Kullanabilirsiniz:

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

Bkz reduceve operator.mulbir açıklama belgeleri.

import functoolsPython 3 + ' da çizgiye ihtiyacınız var .


32
Python3 içinde, reduce()işlevin genel ad alanından kaldırıldığını ve functoolsmodüle yerleştirildiğini unutmayın . Yani python3'te söylemelisin from functools import reduce.
Eugene Yarmash

2
Üçüncü argüman olarak '1' burada gereksizdir, buna ihtiyaç duyulacak bir durum nedir?
wordsforthewise

5
Üçüncü argüman olmadan @wordsforthewise, boş bir diziyi
geçerseniz

1
lambda x,y: x*yayrıca çalışıyoroperator.mul

79

Ben numpy.prodgörevi yerine getirmek için kullanın . Aşağıya bakınız.

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

13
Zaten Numpy kullanıyorsanız kullanışlıdır. Muhtemelen ilk önce bir liste olarak yayınlamanız bile gerekmiyor, bu çoğu durumda işe yarayacakresult = np.prod(mylist)
Nick

4
Dikkat edilmesi gereken iki şey: 1) Özellikle varsayılanı numpy.int32yukarıdaki gibi kullanırsanız taşabilir 2) Küçük listeler için, NumPy'nin bir dizi ayırması gerektiğinden (sık sık tekrarlanırsa)
Disenchanted

1
burada 21'in üzerindeki değerler için taşmanp.prod(np.array(range(1,21)))
PatrickT

İyi bir seçim değil. Taşabilir ve daha yavaştır. deneyin reduce.
Peyman

57

Bir şey içe aktarmaktan ve Python'un daha karmaşık alanlarından kaçınmak istiyorsanız, basit bir döngü kullanabilirsiniz.

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
Küçük not: Python'daki dilimler çok kolaydır ve burada sadece ilkellerle uğraştığımızdan, liste [0] ile başlayıp liste [1:] üzerinden yineleyerek 1 ile başlayan küçük çamurdan kaçınabilirsiniz. Burada daha işlevsel 'azaltma' yanıtları ile rahat olmak uzun vadede değerlidir, çünkü diğer durumlarda da faydalıdır.
kungphu

@kungphu Boş ürün genellikle 1 olarak tanımlanır, boş bir diziyi geçerseniz çözümünüz bir IndexError istisnası atar
Francisco Couzo

@Francisco Kabul, ancak bu fonksiyon muhtemelen gerektiğini boş bir dizi bu işlev için geçersiz giriş olacağından, bu durumda istisna bazı lezzet atmak. Aslında, bu fonksiyon ikiden az değeri olan herhangi bir sekans için anlamlı değildir; bir değeri olan bir diziyi iletir ve 1 ile çarparsanız, aslında orada olmayan bir değer eklediniz, bu da beklenmedik davranışa karşılık geldiğini söyleyebilirim.
kungphu

1
@kungphu, bu yanıtın davranışı doğrudur, yani 1 uzunluk listesinin iletilmesi değeri döndürür ve 0 uzunluk listesinin iletilmesi 1 döndürür. Toplam ([]) değerini 0 veya toplam olarak veren aynı düşünce satırındadır. ([3]) 3 olarak. Bakınız: en.wikipedia.org/wiki/Empty_product
emorris

Matematiksel fonksiyonlarla ilgili görüşünüzü görüyorum. Ancak, pratik bir gelişme durumda, açıkça girişinde çalışmak üzere niyetiyle bir işlev çok nadir bir durum çağırır gerektiğini hiçbir giriş veya geçersiz giriş ne miktarda verilen bir değeri döndürür. Sanırım bu alıştırmanın amacına bağlı: Eğer sadece standart kütüphaneyi kopyalamak istiyorsanız, tamam, belki de insanlara (ya da bir) dilin nasıl ya da nasıl uygulanabileceği hakkında bir şeyler öğretir. Aksi takdirde, geçerli ve geçersiz argümanlar hakkında bir ders vermek için iyi bir fırsatı kaçırdığını söyleyebilirim.
kungphu

14

Başlangıçta Python 3.8, standart kütüphanedeki modüle bir .prodfonksiyon dahil edilmiştir math:

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

Yöntem, bir startdeğerin ürününü (varsayılan: 1) yinelenebilir sayılardan döndürür:

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

>>> 720

Yinelenebilir boşsa, bu üretilecektir 1(veya startvarsa değer).


10

İşte makinemden bazı performans ölçümleri. Bunun uzun süren bir döngüdeki küçük girişler için yapılması durumunda geçerlidir:

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}')

Sonuçlar:

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

Çarpma işleminden önce bir dizi ayırdığı için Numpy'nin daha küçük girişlerde biraz daha yavaş olduğunu görebilirsiniz. Ayrıca Numpy'deki taşmaya dikkat edin.


Sadece meraktan değerlendirme yolunu ekleyebilirsiniz
Mr_and_Mrs_D

Ben şüpheli multiply_functoolsve multiply_numpy bakmak zorunda tarafından aşağı tartılır np, functoolsve operatornitelik aramalarının ardından globalsi. Yerlilere geçmek ister misiniz? _reduce=functools.reduce, _mul = operator.mul` işlev imzasında sonra return _reduce(_mul, iterable)vücutta vb.
Martijn Pieters

1
Ayrıca, numpy sürümü ilk önce sayıları numpy dizisine dönüştürmek zorundadır; normalde bu dönüşümü zamanlamalara dahil etmek gerçekten adil olmazdı. Liste bir kez numpy dizisine dönüştürüldüğünde, np.prod()seçenek 100 öğeden veya daha fazladan başlar.
Martijn Pieters

8

Ben şahsen genel listenin tüm unsurlarını bir araya getiren bir fonksiyon için bunu beğendim:

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

Kompakt, basit şeyler (bir değişken ve bir for döngüsü) kullanıyor ve bana sezgisel geliyor (sorunu nasıl düşündüğüm gibi görünüyor, sadece bir tane al, çarp, sonra bir sonraki ile çarp, vb. )


3
harika, en basit ve en sade.
ghostkraviz

4
Neden olmasın for i in n:, o zaman total *= i? çok daha basit olmaz mıydı?
Munim Munna

Benim için yukarıdaki şekilde çalışmadı.
athul

5

Basit yol:

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

10
just aboutnp.prod(your_Array)
dashesy

3

Numpyprod()bir listenin ürününü döndüren işleve sahiptir veya bu durumda numpy olduğundan, belirli bir eksen üzerindeki bir dizinin ürünüdür:

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

... yoksa yalnızca şunları içe aktarabilirsiniz numpy.prod():

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

2

Bu soruyu bugün buldum None, ancak listede yer alan bir durumun olmadığını fark ettim . Yani, tam çözüm şöyle olacaktır:

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))

Ekleme durumunda:

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
Lütfen cevabınıza biraz açıklama ekleyin. Cevap Nasıl
xenteros

3
Ben chime ve kodu açıklamaya çalışın: Ben şahsen bu kodu çok sevmiyorum, çünkü argümanı veya işlevi olarak dizeyi yorumlayan eval kullanır (ve bu nedenle genellikle giriş verileri işlerken, güvenli olmayan bir şey olarak görüntülenir ). Bundan önceki satır, sınırlayıcı her virgülün yerini bir çarpımla değiştirir *, öyle ki eval bunu çarpımsal olarak kabul eder. Bu performansın, özellikle diğer çözümlere kıyasla nasıl olduğunu merak ediyorum
dennlinger

Vay, çok kötü bir fikir!
Kowalski

1

Bunu şu şekilde istiyorum:

    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

Bu benim kodum:

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]))

sonuç: ('1 * 1 * 2 * 3 * 4', 24)


0

Özyineleme kullanmaya ne dersiniz?

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

-1

Çözümüm:

def multiply(numbers):
    a = 1
    for num in numbers:
        a *= num
        return a

  pass

-1

'' 'Döngü için mantık kullanımını anlamak için tek basit yöntem' ''

Tur = [2,5,7,7,9] x = Turdaki i için 1: x = i * x baskı (x)


Cevabınız bu sorunun tartışılmasına yeni bir şey eklemiyor.
Sid

-3

Hiçbir şey ithal etmemek çok basittir. Bu benim kodum. Bu, listedeki tüm öğeleri çarpan ve ürünlerini döndüren bir işlev tanımlayacaktır.

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

2
DeadChex'in cevabına, piSHOCK cevabına, Shakti Nandan'ın cevabına kopya. Zaten önerilen cevabı göndermeyin.
Munim Munna

ayrıca multi döndürmelidir | - |
Lars
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.