Bagaimana cara melakukan perkalian elemen-bijaksana dari dua daftar?

144

Saya ingin melakukan perkalian bijak elemen, untuk mengalikan dua daftar bersama dengan nilai di Python, seperti yang bisa kita lakukan di Matlab.

Beginilah cara saya melakukannya di Matlab.

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

Sebuah pemahaman daftar akan memberikan 16 entri daftar, untuk setiap kombinasi x * ydari xdari adan ydari b. Tidak yakin bagaimana memetakan ini.

Jika ada yang tertarik kenapa, saya punya dataset, dan ingin mengalikannya dengan Numpy.linspace(1.0, 0.5, num=len(dataset)) =).

xxjjnn
sumber
4
Kenapa kamu menanyakan ini padahal sekarang kamu sudah tentang numpy?
pwuertz
2
Dan omong-omong, ini adalah perkalian berdasarkan elemen, ini bukan perkalian titik.
pwuertz
3
Alternatif: peta (lambda x, y: x * y, list1, list2) #derp ...
xxjjnn

Jawaban:

288

Gunakan pemahaman daftar yang dicampur dengan zip():.

[a*b for a,b in zip(lista,listb)]
gahooa
sumber
9
Di sisi lain, jika mereka ingin melakukan hal lain di luar kasus sepele di sini, OP akan disarankan untuk menggunakan Numpy.
Henry Gomersall
1
Pada Python 2 izip () bisa menjadi pilihan yang lebih baik.
yak
23
Anda juga bisa menggunakan map(lambda x,y:x*y,lista,listb).
mbomb007
Bagaimana jawaban akan berubah jika kita diberikan listbdaripada daftar elemen tipe listbyang diberikan dan kita perlu bekerja untuk mendapatkan satu daftar. Ex. (x, pi, e) dengan [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], bila diambil (x, pi, e) dioperasikan dengan (4, 5, 2) lalu (x, pi, e) dioperasikan dengan (1, 2, 4)… seterusnya.
gxyd
@gxyd Anda harus mengajukan pertanyaan terpisah
mbomb007
88

Karena Anda sudah menggunakan numpy, masuk akal untuk menyimpan data Anda dalam numpylarik daripada daftar. Setelah Anda melakukan ini, Anda mendapatkan hal-hal seperti produk elemen-bijaksana secara gratis:

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])
NPE
sumber
1
Mungkin bukan yang paling ilmiah, tapi saya menghitung waktunya dengan jawaban gahooa menggunakan timeit. Numpy sebenarnya sedikit lebih lambat dari metode zip.
Chase Roberts
1
Dalam kasus saya, di mana daftarnya berisi nilai biner, solusi numpy jauh lebih cepat daripada menggunakan izip.
Serendipity
Untuk kepentingan orang lain yang tiba di sini dari pencarian google, saya telah menyertakan perbandingan waktu di bawah ini.
paddyg
32

Gunakan np.multiply (a, b):

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

Anda dapat mencoba mengalikan setiap elemen dalam satu putaran. Tangan pendek untuk melakukan itu adalah

ab = [a[i]*b[i] for i in range(len(a))]
Nate
sumber
selamat datang di stackoverflow! jawaban kode-saja umumnya tidak disarankan - tambahkan beberapa penjelasan tentang bagaimana ini menjawab pertanyaan penanya.
Corley Brigman
8
@CoretanJuara Saya tidak setuju; ada sedikit perbedaan antara jawaban "Berikut adalah cara untuk melakukan ini: <code>" dan hanya "<code>". Dalam situasi khusus ini, tidak banyak yang bisa dijelaskan selain "kode ini memecahkan masalah Anda".
icedtrees
4
@CoretanJuara Saya tidak setuju; contoh data dengan menampilkan hasil sebenarnya akan lebih membantu
Tjorriemorrie
2
Beginilah cara programmer C, C ++, atau Java yang merupakan pemula Python akan memecahkan masalah. The jawaban yang diterima adalah idiomatik Python.
David Cullen
@Tjorriemorrie hasilnya jelas seperti yang diminta secara eksplisit dalam pertanyaan. mungkin penjelasan tentang bagaimana pemahaman daftar bekerja bisa bagus atau menyebutkan bahwa ini menggunakan pemahaman daftar dan kemudian semua orang dapat melihatnya, jika mereka tidak mengetahuinya.
xuiqzy
10

Namun jawaban lain:

-1... membutuhkan impor
+1... sangat mudah dibaca

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

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

keluaran [10, 22, 36, 52]

Petr Vepřek
sumber
Jika Anda tahu peta, ini adalah solusi yang sangat mudah dibaca! Apakah impor memiliki konsekuensi negatif selain berada di bagian atas file? (editor dapat menyembunyikan impor jika mereka mau) Sejauh yang saya tahu, itu harus tersedia di setiap versi python 2 dan 3!
xuiqzy
9

Cara yang cukup intuitif untuk melakukan ini:

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
Turtleneck
sumber
9

Anda bisa perkalian menggunakan lambda

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

Untuk list yang besar, kita bisa melakukannya dengan cara iter:

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

product_iter_object.next() memberikan setiap elemen dalam daftar keluaran.

Outputnya adalah panjang yang lebih pendek dari dua daftar input.

aady
sumber
4

membuat sebuah array; kalikan setiap daftar dikalikan dengan larik; mengonversi larik menjadi daftar

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]
litepresence
sumber
3

jawaban gahooa benar untuk pertanyaan seperti yang diutarakan pada judul, tetapi jika daftar sudah dalam format numpy atau lebih besar dari sepuluh akan JAUH lebih cepat (3 lipat) serta lebih mudah dibaca, untuk melakukan perkalian numpy sederhana seperti yang disarankan oleh NPE. Saya mendapatkan pengaturan waktu ini:

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

yaitu dari program pengujian berikut.

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))
paddyg
sumber
3

Bisa menggunakan enumerate.

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

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

The mapFungsi bisa sangat berguna di sini. Menggunakan mapkita dapat menerapkan fungsi apa pun ke setiap elemen iterable.

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

Tentu saja:

map(f, iterable)

setara dengan

[f(x) for x in iterable]

Jadi kami bisa mendapatkan solusi kami melalui:

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

Dalam Python 2.x map()artinya: terapkan fungsi ke setiap elemen iterable dan buat daftar baru. Di Python 3.x, mapbuat iterator alih-alih daftar.

Daripada my_mulkita bisa menggunakan muloperator

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+

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

Harap dicatat bahwa karena map()membangun sebuah iterator kami menggunakan *operator unpacking iterable untuk mendapatkan daftar. Pendekatan unpacking sedikit lebih cepat daripada listkonstruktor:

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

Untuk mempertahankan tipe daftar, dan melakukannya dalam satu baris (setelah mengimpor numpy sebagai np, tentunya):

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

atau

list(np.array(a) * np.array(b))
mayypile
sumber
0

Anda dapat menggunakan ini untuk daftar dengan panjang yang sama

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
WOX GAMER
sumber