Multiplying a subset of a list of integers together in python
Let's say I have a list of 10 integers and I want the result of multiplying the 开发者_StackOverflow中文版first 5 together. Is there a pythonic way of doing this? Python seems to be great with lists :)
import operator
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print reduce(operator.mul, [v for (k, v,) in enumerate(l) if k < 5])
>> 120
Edit: Better way to do it
print reduce(operator.mul, l[:5])
>> 120
Lot's of ways. Here's one:
>>> a = range(1,10)
>>> reduce(lambda x,y: x*y, a[:5])
120
When there are many ways to do something, I turn to criteria such as readability or speed to decide which code to use. Here is some code which suggests that use_loop
and use_reduce
are roughly tied in terms of speed (at least for the values tested!)
import operator
import itertools
a=range(1,1000)
def use_loop(a,n):
result=1
for num in a[:n]:
result*=num
return result
def use_reduce(a,n):
return reduce(operator.mul, a[:n])
def use_reduce_lambda(a,n):
return reduce(lambda x,y: x*y, a[:n])
def use_islice_loop(a,n):
result=1
for num in itertools.islice(a,n):
result*=num
return result
def use_islice_reduce(a,n):
return reduce(operator.mul, itertools.islice(a,n))
if __name__=='__main__':
n=50
print(use_loop(a,n))
print(use_reduce(a,n))
print(use_reduce_lambda(a,n))
print(use_islice_loop(a,n))
print(use_islice_reduce(a,n))
Here are the timing results:
% python -mtimeit -s"import test" "test.use_loop(test.a,50)"
10000 loops, best of 3: 16.1 usec per loop
% python -mtimeit -s"import test" "test.use_reduce(test.a,50)"
100000 loops, best of 3: 16.3 usec per loop
% python -mtimeit -s"import test" "test.use_islice_loop(test.a,50)"
10000 loops, best of 3: 19.6 usec per loop
% python -mtimeit -s"import test" "test.use_islice_reduce(test.a,50)"
10000 loops, best of 3: 19.2 usec per loop
% python -mtimeit -s"import test" "test.use_reduce_lambda(test.a,50)"
10000 loops, best of 3: 32.1 usec per loop
At least for the value of a
(1000) and n
(50) tested, itertools.islice
did not seem to help performance. use_reduce_lambda
was significantly slower than it's cousin use_reduce
, which used operator.mul
. The time required to import operator
was not included in the test, however.
Since use_loop
and use_reduce
seem equally fast, I'd suggest using reduce
since its short, idiomatic code should be quite readable to most python programmers. However, in matters of taste I don't think it pays to be too opinionated. Choose what you like best, just be consistent.
PS. As of Python 3+, reduce
is no longer a built-in function, but can be accessed through functools.reduce
.
Using reduce:
reduce(lambda x, y: x*y, mylist[:5])
e.g.,
>>> reduce(lambda x,y:x*y, range(1,5))
24
the reduce()
function applies the given function (here, multiplication) over the first two items of the list, hereby reducing them to one item. This is done until there is only one item in the list. This item is returned as the result. This notation is derived from functional languages.
Iterating through the list:
result=1
for i in mylist[:5]:
result*=i
e.g,
>>> result=1
>>> for i in range(1,5):
result*=i
>>> result
24
This is the most general way of aggregating some function over all items of a list; It is similar to the way this would have been done Java or C.
This is a simple function that will do what you want.
def multiply(args):
x= 1
for arg in args:
x*= arg
return x
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
multiply(l)
>>>362880
multiply(l[:5])
>>>120
精彩评论