简体   繁体   中英

List comprehension to find all multiples of each number in list less than a number

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.

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

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]

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]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM