ฉันจะคูณแต่ละองค์ประกอบในรายการด้วยตัวเลขได้อย่างไร


92

ฉันมีรายชื่อ:

my_list = [1, 2, 3, 4, 5]

ฉันจะคูณแต่ละองค์ประกอบmy_listด้วย 5 ได้อย่างไร ผลลัพธ์ควรเป็น:

[5, 10, 15, 20, 25]

2
ใช้ดีกว่าmap for-loop
Tony

9
และความเข้าใจในรายการ (เกือบตลอดเวลา) ดีกว่าmap (และจะดีกว่าเสมอหากmapต้องการ a lambda)
ShadowRanger

คำตอบ:


133

คุณสามารถใช้การทำความเข้าใจรายการ:

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]

โปรดทราบว่าโดยทั่วไปการทำความเข้าใจรายการเป็นวิธีที่มีประสิทธิภาพมากกว่าในการforวนซ้ำ:

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

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

อีกทางเลือกหนึ่งนี่คือวิธีแก้ปัญหาโดยใช้แพ็คเกจ Pandas ยอดนิยม:

import pandas as pd

s = pd.Series(my_list)

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

หรือหากคุณต้องการเพียงแค่รายการ:

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

ชื่อตัวแปรที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่ไม่ใช่ Pythonic และเป็นรายการไม่ใช่ตัวเลข ดังนั้นฉันขอแนะนำให้ใช้l1และl2เป็นชื่อตัวแปร
Casimir Crystal

4
การใช้ 'l' เป็นตัวแปรยังไม่ได้รับการสนับสนุนเนื่องจากตัวอักษร 'l' และตัวเลข 1 นั้นสับสน ฉันใช้ตัวแปรในคำถามดั้งเดิมของ OP และฉันเชื่อว่าการแก้ไขคำถามของคุณส่งผลร้ายมากกว่าผลดี
Alexander

1
หากคุณคิดว่าการแก้ไขของฉันไม่ดีคุณสามารถแก้ไขคำถามเพื่อปรับปรุงได้ นอกจากนี้เรายังสามารถเลือกตัวแปรอื่น ๆ มากกว่าl1เช่นl_1, list_1ฯลฯ Num_1เหล่านี้ล้วนเป็นดีกว่า
Casimir Crystal

26

วิธีการที่เร็วกว่าอย่างเห็นได้ชัดคือการคูณในลักษณะเวกเตอร์แทนที่จะวนซ้ำรายการ Numpy ได้จัดเตรียมวิธีที่ง่ายและสะดวกสำหรับสิ่งนี้ไว้ให้แล้ว

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

โปรดทราบว่าสิ่งนี้ใช้ไม่ได้กับรายการเนทีฟของ Python หากคุณคูณตัวเลขด้วยรายการมันจะทำซ้ำรายการที่มีขนาดเท่ากับจำนวนนั้น

In [15]: my_list *= 1000

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

หากคุณต้องการแนวทางที่ใช้ Python อย่างแท้จริงโดยใช้การทำความเข้าใจรายการนั้นเป็นวิธีที่ 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]

นอกเหนือจากความเข้าใจในรายการแล้วคุณยังสามารถใช้map()ฟังก์ชันในตัวได้ดังต่อไปนี้:

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

รหัสนี้ผ่านรายการทั้งหมดภายในmy_listเพื่อ5's __mul__วิธีการและส่งกลับ iterator เหมือนวัตถุ (ในหลาม 3.x) จากนั้นคุณสามารถแปลงตัววนซ้ำเป็นรายการโดยใช้list()ฟังก์ชันในตัว (ใน Python-2.x คุณไม่ต้องการสิ่งนั้นเพราะmapส่งคืนรายการตามค่าเริ่มต้น)

เกณฑ์มาตรฐาน:

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)

ฉันสนใจว่าทำไมวิธีการ numpy ถึง 'เร็วขึ้นอย่างเห็นได้ชัด'? คุณช่วยอธิบายหรือชี้ให้ฉันดูแหล่งข้อมูลได้ไหม ฉันไม่แน่ใจว่า vectorization คืออะไร
Aerinmund Fagelson

1
@AerinmundFagelson ที่นี่ -> stackoverflow.com/questions/35091979/…
Kasravnd

@ Kasramvd ลิงก์นั้นไม่ถูกต้อง ลิงก์กล่าวถึงความหมายที่แตกต่างกันของvectorizationเป็น single-instruction-multiple-data (ใช้การดำเนินการกับข้อมูลจำนวนมากพร้อมกันเช่นเดียวกับ GPU) ในบริบทของ NumPy vectorizationหมายถึงการใช้ C ลูปที่คอมไพล์ล่วงหน้าอย่างรวดเร็วเพื่อดำเนินการกับลำดับข้อมูลแทนที่จะเป็น Python บริสุทธิ์
xjcl


19

คุณสามารถทำได้ในสถานที่ดังนี้:

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

สิ่งนี้ไม่จำเป็นต้องมีการนำเข้าเพิ่มเติมและเป็น pythonic มาก


นอกจากนี้: แนวคิดนี้เรียกว่าการเข้าใจรายการหากคุณต้องการค้นหาข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้
Michael

1
ฉันอยากจะมากกว่าl = [x * 5 for x in l] l[:] = [x * 5 for x in l]หลังสร้างรายการใหม่จากนั้นใช้เพื่อเขียนทับเนื้อหาlซึ่งตรงข้ามกับการกำหนดข้อมูลอ้างอิงใหม่ซึ่งมีราคาถูกกว่า หากคุณกังวลเกี่ยวกับอวกาศจริงๆเพียงแค่วนซ้ำและกลายพันธุ์ในสถานที่
cs95

6

เนื่องจากฉันคิดว่าคุณยังใหม่กับ Python มาลองทำแบบยาว ๆ วนซ้ำผ่านรายการของคุณโดยใช้สำหรับการวนซ้ำและคูณและต่อท้ายแต่ละองค์ประกอบในรายการใหม่

ใช้สำหรับวนซ้ำ

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

การใช้ความเข้าใจในรายการสิ่งนี้ก็เหมือนกับการใช้ for-loop แต่มี 'pythonic' มากกว่า

lst = [5, 20 ,15]

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

"ทางยาว" ในทางใดดีกว่ากัน? มันยาวกว่า - จึงอ่านยากกว่า - และเขียนไม่ง่ายเลย
lirtosiast

1
โอเคบางทีคุณอาจรู้สึกผิดกับชื่อของฉันและฉันไม่เคยบอกว่ามันดีกว่านี้แค่พยายามแสดงให้เขาเห็นว่าทำได้โดยไม่ต้องใช้ความเข้าใจ เนื่องจากประสบการณ์ของฉันเมื่อฉันยังใหม่ใน python ฉันไม่สามารถเข้าใจแนวคิดเรื่องความเข้าใจได้ง่าย
wasp8898

ตกลง. ฉันไม่สามารถเชื่อมโยงโดยตรงได้เนื่องจากฉันเริ่มต้นด้วยภาษาที่ใช้งานได้
lirtosiast

ฉันเห็นดีที่นั่น ฉันแก้ไขคำตอบเพื่อรวมวิธีการที่มีประสิทธิภาพไว้ด้วย
wasp8898

4

ด้วยแผนที่ (ไม่ดีเท่า แต่มีแนวทางอื่นในการแก้ปัญหา):

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

นอกจากนี้หากคุณใช้อาร์เรย์ numpy หรือ numpy คุณสามารถใช้สิ่งนี้:

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

ทำไมไม่ใช้แลมบ์ดาแทนการกำหนดฟังก์ชัน timesfive?
วิมานยู

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

เป็นวิธีหนึ่งที่คุณสามารถทำได้ ... ครูของคุณอาจรู้วิธีที่ซับซ้อนน้อยกว่ามากซึ่งอาจครอบคลุมในชั้นเรียน


คุณสามารถทำได้โดยไม่ต้องใช้คำสั่งนำเข้าโดยใช้นิพจน์แลมบ์ดา นอกจากนี้ตัวอย่างข้อมูลของคุณจะส่งคืนวัตถุแผนที่ซึ่งไม่มีประโยชน์เว้นแต่จะส่งไปยังรายการ รายการ (แผนที่ (แลมบ์ดา x: 5 * x, my_list))
castle-bravo

@ castle-bravo ประโยชน์ของมันขึ้นอยู่กับสิ่งที่คุณต้องทำ ... มีหลายวิธีในการบรรลุวิธีแก้ปัญหานี้ (ตามที่ฉันพูดถึง ... )
Joran Beasley

4
กรุณาอย่าสอนให้คนอื่นใช้mapด้วยlambda; ในทันทีที่คุณต้องการlambdaคุณจะเข้าใจดีกว่าด้วยการเข้าใจรายการหรือนิพจน์ตัวสร้าง หากคุณฉลาดคุณสามารถทำให้mapการทำงานโดยไม่ต้องlambdaมาก SA เช่นในกรณีนี้map((5).__mul__, my_list)แม้ในกรณีนี้โดยเฉพาะอย่างยิ่งต้องขอบคุณการเพิ่มประสิทธิภาพบางอย่างในล่ามรหัสไบต์สำหรับง่ายintคณิตศาสตร์[x * 5 for x in my_list]จะเร็วขึ้นเช่นเดียวกับการเพิ่มเติม Pythonic และง่าย .
ShadowRanger

1

การคูณแต่ละองค์ประกอบmy_listด้วยk:

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

ที่เกิดขึ้นใน: [5, 10, 15, 20]


-1

วิธีที่ดีที่สุดคือใช้ list compleance:

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

ผลตอบแทน: [-1, -2, -3]


นี่เป็นเพียงคำตอบที่ได้รับการยอมรับและเปลี่ยนเป็นฟังก์ชัน คุณอาจทำได้ด้วยคำตอบมากกว่าครึ่งหนึ่งใน SO แต่ไม่ได้เพิ่มอะไรเลยและไม่ใช่สิ่งที่ OP ถาม
Alexander
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.