简体   繁体   中英

python combination of several lists items

I have several lists like: [1,2,3],[1,3],[1,2,3,4] . I need combinations of these values (length equal to the number of lists). Problem is that itertools.product doing all combinations (I don't want for example (1,1,1) because all items are same or [(1,3,2),(2,3,1)] because items 1 and 3 only switch. I wrote a solution, where items in the tuple are unique and the result does not contain the same tuple after sort

a = list(itertools.product(*[[1,2,3],[1,3],[1,2,3,4]]))
res = []
for item in a:
    if (len(item) == len(set(item))):
        is_unique = True
        for r in res:
            if sorted(item) == sorted(r):
                is_unique = False
        if is_unique:
            res.append(item)

with this result:

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

The first problem is, that this code is really time-consuming if I have several arrays and every array contains many values (positions). The second problem is that IT DEPENDS on the order in a tuple (the second position can be only 1 and 3) so I cant use itertools.combination() on all unique value from input lists.

Is there any better solution?

Here is a solution using set and len to filter out duplicates:

ll = [[1,2,3],[1,3],[1,2,3,4]]

c1 = itertools.product(*ll)
# [(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 3, 1), (2, 3, 2), (2, 3, 3), (2, 3, 4), (3, 1, 1), (3, 1, 2), (3, 1, 3), (3, 1, 4), (3, 3, 1), (3, 3, 2), (3, 3, 3), (3, 3, 4)]
c2 = set(frozenset(c) for c in c1)
# {frozenset({3, 4}), frozenset({1, 4}), frozenset({2, 3, 4}), frozenset({2, 3}), frozenset({1, 2, 4}), frozenset({1, 2}), frozenset({3}), frozenset({1}), frozenset({1, 2, 3}), frozenset({1, 3}), frozenset({1, 3, 4})}
c3 = set(c for c in c2 if len(c) == len(ll))
# {frozenset({1, 2, 3}), frozenset({2, 3, 4}), frozenset({1, 3, 4}), frozenset({1, 2, 4})}

Your code is good, however the for loop is very time consuming. Try this instead:

a = list(itertools.product(*[[1,2,3],[1,3],[1,2,3,4]]))
s = set()
res = []
for item in a:
    if (len(item) == len(set(item))):
        k=tuple(sorted(item))
        if k not in s: 
            res.append(item)
            s.add(k)

Output:

>>> print(res)
[(1, 3, 2), (1, 3, 4), (2, 1, 4), (2, 3, 4)]

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