简体   繁体   中英

Remove common factors from list of lists in Python

I have a list of lists made with

itertools.product(range(5), repeat=3)

which gives

[[0 0 0]
 [0 0 1]
 [0 0 2]
 [0 0 3]
 [0 0 4]
 [0 1 0]
 [0 1 1]
... etc]

I want to remove all lists that have common integer factors except the trivial cases of 0 and 1 because then that would match all lists. For example [0 0 2] is [0 0 1] multiplied by 2 so I'd want to remove [0 0 2]. Another example would be [3 3 3] which is [1 1 1] multiplied by 3 so I'd want to remove [3 3 3]. What is the most efficient way to do this?

It sounds like you want all the combinations that don't share a common factor (other than 1, obviously). For example: [2, 3, 4] should be in your list because you can't factor a single number shared by all of them other than one. [2,4,0] on the other hand can be thought of as 2 * [1, 2, 0] . You can use math.gcd to find the GCD — GCD is associative, so you can nest it (or use reduce() for a general solution ).

from itertools import product
from math import gcd
from functools import reduce

test = lambda p: reduce(gcd, p) == 1

[p for p in product(range(5), repeat=3) if test(p)]

Result

[(0, 0, 1),
 (0, 1, 0),
 (0, 1, 1),
 (0, 1, 2),
 (0, 1, 3),
 (0, 1, 4),
 (0, 2, 1),
 (0, 2, 3),
 ...
 (4, 2, 3),
 (4, 3, 0),
 (4, 3, 1),
 (4, 3, 2),
 (4, 3, 3),
 (4, 3, 4),
 (4, 4, 1),
 (4, 4, 3)]

Because of the way gcd works you will need to treat [0,0,0] as a special case.

Creating list with itertools.product() and removing items you don't need is inefficient by itself: it would be better to skip those items at the list generation phase.

But if you want to remove items anyway, you can use approach similar to Sieve of Eratosthenes :

Take some list, for example (0,0,1) , muliple it by 2 - you get (0,0,2) - remove it. Then multiply by 3 - you get (0,0,3) - remove it as well. Then do the same with multiplier 4 and 5. If any of such lists were found, remove original list as well.

Take next item of modified list of lists and repeat the process.

In the simpliest approach you may try multipliers from 2 to 5 all the time. If you want to optimize it, you may first find max value and check up to 5//max_value only.

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