Two divisible lists

Viewed 66

I need this function to return True if all of the numbers of list_1 can be divisible by at least one number in list_2. I tried to use the all function for this like :

for num1 in list_1: 
    if all(num1 % num2 == 0 for num2 in list_2)
    return True

The problem with my solution is that it checks if ALL the numbers in list_1 can be divisible by ALL the numbers in list_2, and that is not what I require.

I'm wondering if there is a way to do it such that all the numbers of list_1 have atleast one factor in list_2? An example would be:

List_1 = [15, 10, 4, 8, 12] List_2 = [2, 5, 3] output True

List_1 = [15, 10, 7, 8, 12] List_2 = [2, 5, 3] output False

It is False in the 2nd situation as 7 can't be divided by any of the numbers in list_2.

2 Answers

You can combine all and any in a comprehension:

>>> l1=[8,10,20]
>>> l2=[2,3]
>>> any(all(n1%n2==0 for n1 in l1) for n2 in l2)
True

If you want to check any number in list1 should be divisible by at least one number in list 2, you can restructure above statement as follows:

>>> l1,l2=[15, 10, 4, 8, 12],[2, 5, 3]
>>> all(any(n1%n2 for n2 in l2) for n1 in l1)
True

You're almost there. List comprehensions can contain an arbitrary number of variables, in which case all combinations of them will be considered. You can simply say

return all(l1_elm % l2_elm == 0 for l1_elm in List1 for l2_elm in List2)

This is equivalent to

for l1_elm in List1:
    for l2_elm is List2:
        # if this doesn't evaluate to 0
        if l1_elm % l2_elm:
            return False
return True

By the way, it's idiomatic in python to use snake_case for variables and PascalCase for classes, so your List1 and List2 should ideally be written as list_1 (or just list1) and list_2, respectively.

@ThePyGuy also makes a good point. The modulo operator fails if the second argument is 0 with ZeroDivisionError: integer division or modulo by zero. If you expect that List2 might contain a 0 value, you should also check for that before attempting to divide, i.e. modify the condition to if l2_elm == 0 or l1_elm % l2_elm.

EDIT: OP has indicated that they actually meant check if all values in List1 are divisible by any values in List2. For that case, the following code is appropriate

return any(all(l1_elm % l2_elm == 0 for l1_elm in List1) for l2_elm in List2)

Which is exactly @ThePyGuy's original answer. This is equivalent to

for l2_elm in List2:
    all_divisible = True
    for l1_elm in List1:
        if l1_elm % l2_elm:
            all_divisible = False
            # this l2_elm didn't work. no need to check further List1
            # values for divisibility
            break
    # this particular l2_elm divided everything successfully, so
    # return True
    if all_divisible:
        return True
# nothing worked, so fail
return False
Related