Làm cách nào để nhân từng phần tử trong danh sách với một số?


Câu trả lời:


134

Bạn chỉ có thể sử dụng một cách hiểu danh sách:

my_list = [1, 2, 3, 4, 5]
my_new_list = [i * 5 for i in my_list]

>>> print(my_new_list)
[5, 10, 15, 20, 25]

Lưu ý rằng việc hiểu danh sách thường là cách hiệu quả hơn để thực hiện một forvòng lặp:

my_new_list = []
for i in my_list:
    my_new_list.append(i * 5)

>>> print(my_new_list)
[5, 10, 15, 20, 25]

Thay vào đó, đây là một giải pháp sử dụng gói Pandas phổ biến:

import pandas as pd

s = pd.Series(my_list)

>>> s * 5
0     5
1    10
2    15
3    20
4    25
dtype: int64

Hoặc, nếu bạn chỉ muốn danh sách:

>>> (s * 5).tolist()
[5, 10, 15, 20, 25]

Tên biến bắt đầu bằng chữ hoa không phải là Pythonic. Và chúng là danh sách, không phải số. Vì vậy, tôi đề nghị sử dụng l1l2làm tên biến.
Casimir Crystal

4
Việc sử dụng 'l' như một biến cũng không được khuyến khích vì chữ 'l' và số 1 dễ bị nhầm lẫn. Tôi đã sử dụng các biến trong câu hỏi ban đầu của OP và tôi tin rằng việc chỉnh sửa câu hỏi của bạn có hại nhiều hơn là có lợi.
Alexander

1
Nếu bạn cảm thấy bản chỉnh sửa của tôi không tốt, bạn có thể chỉnh sửa câu hỏi để cải thiện nó. Ngoài ra, chúng ta có thể chọn biến khác chứ không phải l1như l_1, list_1vv Đây là tất cả tốt hơn Num_1.
Casimir Crystal

26

Một cách tiếp cận nhanh hơn rất nhiều là thực hiện phép nhân theo cách được vector hóa thay vì lặp lại danh sách. Numpy đã cung cấp một cách rất đơn giản và tiện dụng cho việc này mà bạn có thể sử dụng.

>>> import numpy as np
>>> 
>>> my_list = np.array([1, 2, 3, 4, 5])
>>> 
>>> my_list * 5
array([ 5, 10, 15, 20, 25])

Lưu ý rằng điều này không hoạt động với danh sách gốc của Python. Nếu bạn nhân một số với một danh sách, nó sẽ lặp lại các mục có cùng kích thước của số đó.

In [15]: my_list *= 1000

In [16]: len(my_list)
Out[16]: 5000

Nếu bạn muốn có một cách tiếp cận dựa trên Python thuần túy bằng cách sử dụng khả năng hiểu danh sách về cơ bản là cách tốt nhất của Pythonic.

In [6]: my_list = [1, 2, 3, 4, 5]

In [7]: [5 * i for i in my_list]
Out[7]: [5, 10, 15, 20, 25]

Bên cạnh việc hiểu danh sách, như một cách tiếp cận hàm thuần túy, bạn cũng có thể sử dụng map()hàm tích hợp như sau:

In [10]: list(map((5).__mul__, my_list))
Out[10]: [5, 10, 15, 20, 25]

Đoạn mã này chuyển tất cả các mục trong phương thức my_listto 5's __mul__và trả về một đối tượng giống như trình lặp (trong python-3.x). Sau đó, bạn có thể chuyển đổi trình lặp thành danh sách bằng cách sử dụng list()hàm tích hợp sẵn (trong Python-2.x, bạn không cần điều đó vì maptrả về danh sách theo mặc định).

điểm chuẩn:

In [18]: %timeit [5 * i for i in my_list]
463 ns ± 10.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [19]: %timeit list(map((5).__mul__, my_list))
784 ns ± 10.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [20]: %timeit [5 * i for i in my_list * 100000]
20.8 ms ± 115 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [21]: %timeit list(map((5).__mul__, my_list * 100000))
30.6 ms ± 169 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)


In [24]: arr = np.array(my_list * 100000)

In [25]: %timeit arr * 5
899 µs ± 4.98 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Tôi quan tâm đến lý do tại sao phương pháp numpy 'nhanh hơn rất nhiều'? Bạn có thể giải thích hoặc chỉ cho tôi một số tài nguyên? Tôi không chắc vectơ hóa là gì.
Aerinmund Fagelson

1
@AerinmundFagelson Đây -> stackoverflow.com/questions/35091979/…
Kasravnd

@Kasramvd Liên kết đó không chính xác. Liên kết thảo luận về một ý nghĩa khác của vectơ hóa là dữ liệu một lệnh-nhiều dữ liệu (áp dụng một phép toán cho nhiều dữ liệu cùng một lúc, như GPU làm). Trong ngữ cảnh của NumPy, vectơ hóa đề cập đến việc sử dụng các vòng lặp C được biên dịch trước nhanh chóng để hoạt động trên một chuỗi dữ liệu, thay vì Python thuần túy.
xjcl


19

Bạn có thể làm điều đó tại chỗ như sau:

 l = [1, 2, 3, 4, 5]
 l[:] = [x * 5 for x in l]

Điều này không yêu cầu nhập khẩu bổ sung và rất khó.


Ngoài ra: khái niệm được gọi là đọc hiểu danh sách nếu bạn muốn tra cứu thêm thông tin về nó.
Michael

1
Tôi muốn l = [x * 5 for x in l]kết thúc l[:] = [x * 5 for x in l]. Sau đó tạo một danh sách mới, sau đó sử dụng nó để ghi đè lên nội dung của thay lvì chỉ gán lại tham chiếu rẻ hơn. Nếu bạn thực sự lo lắng về không gian, chỉ cần lặp lại với một vòng lặp và biến đổi tại chỗ.
cs95

6

Vì tôi nghĩ bạn chưa quen với Python, hãy làm một chặng đường dài, hãy lặp lại qua danh sách của bạn bằng vòng lặp for, nhân lên và nối từng phần tử vào một danh sách mới.

sử dụng vòng lặp for

lst = [5, 20 ,15]
product = []
for i in lst:
    product.append(i*5)
print product

sử dụng khả năng hiểu danh sách, điều này cũng giống như sử dụng vòng lặp for nhưng 'pythonic' hơn

lst = [5, 20 ,15]

prod = [i * 5 for i in lst]
print prod

Làm thế nào là "đường dài" trong bất kỳ cách nào tốt hơn? Nó dài hơn — do đó khó đọc hơn — và không dễ viết hơn.
lirtosiast

1
Được rồi, có thể bạn đã có ấn tượng sai về tiêu đề của tôi và tôi chưa bao giờ nói rằng nó tốt hơn bất kỳ, chỉ đang cố gắng chỉ cho anh ấy cách làm điều đó mà không cần sử dụng khả năng hiểu. bởi vì theo kinh nghiệm của tôi khi tôi mới sử dụng python, tôi không thể nắm bắt khái niệm hiểu một cách dễ dàng.
wasp8898

Ờ được rồi. Tôi không thể liên hệ trực tiếp vì tôi đã bắt đầu với các ngôn ngữ chức năng.
lirtosiast

Tôi hiểu rồi. Tôi đã chỉnh sửa câu trả lời để bao gồm cả cách làm hiệu quả.
wasp8898

4

Với bản đồ (không tốt bằng, nhưng cách tiếp cận vấn đề khác):

list(map(lambda x: x*5,[5, 10, 15, 20, 25]))

ngoài ra, nếu bạn tình cờ sử dụng mảng không có hạt hoặc nhiều mảng, bạn có thể sử dụng điều này:

import numpy as np
list(np.array(x) * 5)

Tại sao không sử dụng lambda thay vì xác định hàm timesfive?
Vimanyu

2
from functools import partial as p
from operator import mul
map(p(mul,5),my_list)

là một cách bạn có thể làm được ... giáo viên của bạn có thể biết một cách ít phức tạp hơn nhiều mà có lẽ đã được đề cập trong lớp


Bạn có thể làm điều đó mà không cần câu lệnh nhập bằng biểu thức lambda. Ngoài ra, đoạn mã của bạn trả về một đối tượng bản đồ, đối tượng này sẽ vô dụng trừ khi được truyền vào danh sách. danh sách (bản đồ (lambda x: 5 * x, my_list)).
Castle-bravo

@ castle-bravo tính hữu dụng của nó phụ thuộc vào những gì bạn cần phải làm gì với nó ... có rất nhiều cách để hoàn thành giải pháp này (như tôi đề cập ...)
Joran Beasley

4
Xin đừng dạy mọi người sử dụng mapvới lambda; ngay lập tức bạn cần một lambda, bạn sẽ tốt hơn với khả năng hiểu danh sách hoặc biểu thức trình tạo. Nếu bạn khéo léo, bạn có thể thực hiện mapcông việc mà không cần quá lambdanhiều, ví dụ như trong trường hợp này map((5).__mul__, my_list), mặc dù trong trường hợp cụ thể này, nhờ một số tối ưu hóa trong trình thông dịch mã byte cho phép inttoán đơn giản , [x * 5 for x in my_list]nhanh hơn, cũng như Pythonic và đơn giản hơn .
ShadowRanger

1

Nhân từng phần tử my_listvới k:

k = 5
my_list = [1,2,3,4]
result = list(map(lambda x: x * k, my_list))

dẫn đến: [5, 10, 15, 20]


-1

Cách tốt nhất là sử dụng khả năng hiểu danh sách:

def map_to_list(my_list, n):
# multiply every value in my_list by n
# Use list comprehension!
    my_new_list = [i * n for i in my_list]
    return my_new_list
# To test:
print(map_to_list([1,2,3], -1))

Trả về: [-1, -2, -3]


Điều này chỉ nhận câu trả lời được chấp nhận và biến nó thành một hàm. Bạn có thể làm điều đó với hơn một nửa số câu trả lời trên SO, nhưng nó không thêm bất cứ điều gì và không phải là những gì OP yêu cầu.
Alexander
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.