İki listenin öğe bazında çarpımı nasıl yapılır?


137

Matlab'da yapabileceğimiz gibi, iki listeyi Python'daki değerle birlikte çarpmak için bir eleman akıllıca çarpma yapmak istiyorum.

Matlab'da böyle yapardım.

a = [1,2,3,4]
b = [2,3,4,5]
a .* b = [2, 6, 12, 20]

Liste kavraması her kombinasyon için, 16 liste girişlerini verecekti x * yarasında xgelen ave ygelen b. Bunun nasıl eşleneceğinden emin değilim.

Birisi neden ilgileniyorsa, bir veri setim var ve bunu çarpmak istiyorum Numpy.linspace(1.0, 0.5, num=len(dataset)) =).


4
Niye şimdi numpy hakkında olduğunuzda bunu soruyorsun?
pwuertz

2
Ve bu arada, bu eleman bazında çarpma, bu bir nokta ürünü değil.
pwuertz

3
Alternatif: harita (lambda x, y: x * y, liste1, liste2) #derp ...
xxjjnn

Yanıtlar:


284

İle karışık bir liste anlama kullanın zip().

[a*b for a,b in zip(lista,listb)]

9
Öte yandan, buradaki önemsiz davanın ötesinde başka bir şey yapmak istiyorlarsa, OP'nin Numpy'yi kullanması tavsiye edilir.
Henry Gomersall

1
Python 2'de izip () daha iyi bir seçim olabilir.
yak

23
Ayrıca kullanabilirsiniz map(lambda x,y:x*y,lista,listb).
mbomb007

Tipik listbbir elemanlar listesi yerine bize verilirse cevap nasıl değişir listbve tek bir liste elde etmek için çalışmamız gerekir. Ör. (x, pi, e) [[4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)] ile, (4, 5, 2) ile çalıştırılan (x, pi, e) alındıktan sonra (1, 2, 4) ile çalıştırılan (x, pi, e) ... vb.
gxyd

@gxyd Ayrı bir soru sormalısınız
mbomb007

88

Zaten kullandığınızdan numpy, verilerinizi numpyliste yerine bir dizide saklamak mantıklıdır . Bunu yaptıktan sonra, element-wise ürünleri gibi şeyleri ücretsiz olarak alırsınız:

In [1]: import numpy as np

In [2]: a = np.array([1,2,3,4])

In [3]: b = np.array([2,3,4,5])

In [4]: a * b
Out[4]: array([ 2,  6, 12, 20])

1
Belki en bilimsel değil, ama bunu timeit kullanarak gahooa'nın cevabına göre zamanladım. Numpy aslında zip yönteminden biraz daha yavaştır.
Chase Roberts

1
Benim durumumda, listelerin ikili değerler içerdiği durumlarda, numpy çözümü izip kullanmaktan çok daha hızlıydı.
Serendipity

Buraya bir google aramasından gelen diğerlerinin yararına aşağıda bir timeit karşılaştırması ekledim.
paddyg

31

Np.multiply (a, b) kullanın:

import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)

21

Her öğeyi bir döngü içinde çarpmayı deneyebilirsiniz. Bunu yapmak için kısa el

ab = [a[i]*b[i] for i in range(len(a))]

stackoverflow'a hoş geldiniz! sadece kod yanıtları genellikle önerilmez - lütfen bunun soru sorusunu nasıl çözdüğüne dair biraz açıklama ekleyin.
Corley Brigman

7
@CorleyBrigman Katılıyorum; "İşte bunu yapmanın bir yolu: <code>" ve sadece "<code>" şeklinde bir cevap arasında çok az fark vardır. Bu özel durumda, "bu kod sorununuzu çözer" dışında açıklanacak çok az şey vardır.
icedtrees

4
@CorleyBrigman Katılıyorum; sonuçları görüntüleyen örnek veriler aslında daha yararlı olacaktır
Tjorriemorrie

2
Python acemi olan bir C, C ++ veya Java programcısı sorunu bu şekilde çözecektir. Kabul edilen cevap deyimsel Python'dur.
David Cullen

@Tjorriemorrie, soruda açıkça talep edildiği için sonuçlar açıktır. belki de liste kavrayışının nasıl işlediğine dair bir açıklama ya da bunun liste kavrayışından faydalandığını ve herkes bilmiyorsa bunu arayabilir.
xuiqzy

10

Yine başka bir cevap:

-1... ithalat gerektirir
+1... çok okunabilir

import operator
a = [1,2,3,4]
b = [10,11,12,13]

list(map(operator.mul, a, b))

çıkışlar [10, 22, 36, 52]


Haritayı biliyorsanız, bu gerçekten okunabilir bir çözümdür! İçe aktarma işleminin dosyanın üstünde olmanın dışında herhangi bir olumsuz etkisi var mı? (editörler istedikleri takdirde ithalat gizleyebilir) Görebildiğim kadarıyla, her python 2 ve 3 sürümünde mevcut olmalıdır!
xuiqzy

9

Bunu yapmanın oldukça sezgisel yolu:

a = [1,2,3,4]
b = [2,3,4,5]
ab = []                        #Create empty list
for i in range(0, len(a)):
     ab.append(a[i]*b[i])      #Adds each element to the list

9

kullanarak çarpabilirsin lambda

foo=[1,2,3,4]
bar=[1,2,5,55]
l=map(lambda x,y:x*y,foo,bar)

4

Büyük listeler için bunu yineleyebiliriz:

product_iter_object = itertools.imap(operator.mul, [1,2,3,4], [2,3,4,5])

product_iter_object.next() çıktı listesindeki her bir öğeyi verir.

Çıktı, iki girdi listesinden daha kısa olanın uzunluğu olacaktır.


4

bir dizi oluşturmak; her listenin diziyi çarpması; diziyi listeye dönüştür

import numpy as np

a = [1,2,3,4]
b = [2,3,4,5]

c = (np.ones(len(a))*a*b).tolist()

[2.0, 6.0, 12.0, 20.0]

3

gahooa'nın cevabı başlıkta ifade edilen soru için doğrudur, ancak listeler zaten numpy biçimindeyse veya ondan büyükse, tarafından önerilen basit numpy çarpımı yapmak için ÇOK daha hızlı (3 büyüklük sırası) ve daha okunabilir olacaktır. NPE. Bu zamanlamaları alıyorum:

0.0049ms -> N = 4, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0075ms -> N = 4, a = [i for i in range(N)], c = a * b
0.0167ms -> N = 4, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 4, a = np.arange(N), c = a * b
0.0171ms -> N = 40, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0095ms -> N = 40, a = [i for i in range(N)], c = a * b
0.1077ms -> N = 40, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 40, a = np.arange(N), c = a * b
0.1485ms -> N = 400, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0397ms -> N = 400, a = [i for i in range(N)], c = a * b
1.0348ms -> N = 400, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0020ms -> N = 400, a = np.arange(N), c = a * b

yani aşağıdaki test programından.

import timeit

init = ['''
import numpy as np
N = {}
a = {}
b = np.linspace(0.0, 0.5, len(a))
'''.format(i, j) for i in [4, 40, 400] 
                  for j in ['[i for i in range(N)]', 'np.arange(N)']]

func = ['''c = [a*b for a,b in zip(a, b)]''',
'''c = a * b''']

for i in init:
  for f in func:
    lines = i.split('\n')
    print('{:6.4f}ms -> {}, {}, {}'.format(
           timeit.timeit(f, setup=i, number=1000), lines[2], lines[3], f))

3

Numaralandırma kullanabilir.

a = [1, 2, 3, 4]
b = [2, 3, 4, 5]

ab = [val * b[i] for i, val in enumerate(a)]

3

mapBuradaki görevi çok yararlı olabilir. Kullanarak map, bir yinelenebilir öğenin her öğesine herhangi bir işlev uygulayabiliriz.

Python 3.x

>>> def my_mul(x,y):
...     return x*y
...
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>>
>>> list(map(my_mul,a,b))
[2, 6, 12, 20]
>>>

Elbette:

map(f, iterable)

eşittir

[f(x) for x in iterable]

Böylece çözümümüzü şu yolla elde edebiliriz:

>>> [my_mul(x,y) for x, y in zip(a,b)]
[2, 6, 12, 20]
>>>

Python map()2.x'te: bir yinelenebilir öğenin her öğesine bir işlev uygulamak ve yeni bir liste oluşturmak. Python 3.x'te maplisteler yerine yineleyiciler oluşturun.

Operatör my_mulkullanmak yerinemul

Python 2.7

>>>from operator import mul # import mul operator
>>>a = [1,2,3,4]
>>>b = [2,3,4,5]
>>>map(mul,a,b)
[2, 6, 12, 20]
>>>

Python 3.5 ve üzeri

>>> from operator import mul
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>> [*map(mul,a,b)]
[2, 6, 12, 20]
>>>

map()Bir yineleyici *oluşturduğundan, bir liste almak için yinelenebilir ambalajlama operatörü kullandığımızı lütfen unutmayın . Paketten çıkarma yaklaşımı kurucudan biraz daha hızlıdır list:

>>> list(map(mul,a,b))
[2, 6, 12, 20]
>>>

1

Liste türünü korumak ve bir satırda yapmak için (elbette nump'yi np olarak içe aktardıktan sonra):

list(np.array([1,2,3,4]) * np.array([2,3,4,5]))

veya

list(np.array(a) * np.array(b))

0

bunu aynı uzunluktaki listeler için kullanabilirsiniz

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
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.