Reputation: 2405
I'm trying to write a function that will find all numbers that are a multiple of at least one number in a list where the multiple is less than a certain number. Here's what I've tried so far:
def MultiplesUnderX(MultArray,X):
'''
Finds all the multiples of each value in MultArray that
are below X.
MultArray: List of ints that multiples are needed of
X: Int that multiples will go up to
'''
return [i if (i % x == 0 for x in MultArray) else 0 for i in range(X)]
For example, MultiplesUnderX([2,3],10) would return [2,3,4,6,8,9]. I'm a little unsure how to do this with the for loop inside of the list comprehension.
Upvotes: 4
Views: 3888
Reputation: 71461
You can use the Python any() function to check if there is at least one instance of a divider in MultArray:
def MultiplesUnderX(MultArray,X):
return [i for i in range(X) if any(i % x == 0 for x in MultArray)]
Upvotes: 8
Reputation: 10883
Another version of this algorithm which may be more efficient if the list is mostly co-prime, you can just use range(i, X, i)
to generate only the multiples of i
, then use heapq.merge
to merge the iterators such that the iterator returned is sorted.
The last step is to eliminate duplicates as you go:
import heapq
def all_multiples(multi_list, max_N):
gens = []
for fac in sorted(set(multi_list)):
# In Python 3 this is a generator of all multiples of "fac" less
# than max_N. In Python 2 use xrange
gens.append(range(fac, max_N, fac))
# This will do a heap merge on the generators (which are already sorted)
o = heapq.merge(*gens)
last = None
for val in o:
if val != last:
yield val
last = val
if __name__ == "__main__":
multi_list = [2, 4, 7]
print(list(all_multiples(multi_list, 12)))
# [2, 4, 6, 7, 8, 10]
Upvotes: 0
Reputation: 3939
You can use the Python built-in function any
which returns True
if the iterable passed in contains any truth-y values in combination with a conditional at the end of the list comprehension limiting the list to only elements that satisfy the any
call.
def get_multiples_under(factors, max):
return [i for i in xrange(1, max) if any(i % factor == 0 for factor in factors)]
Your desired output is shown as such:
multiples = [2, 3]
print get_multiples_under(multiples, 10)
# [2, 3, 4, 6, 8, 9]
Upvotes: 1