-1
\$\begingroup\$

I tried to get the all unique pair combinations from a list.

Here is what I have done so far,

import itertools

# Unique Combination Pairs for list of elements
def uniqueCombinations(list_elements):
    l = list(itertools.combinations(list_elements, 2))
    s = set(l)
    # print('actual', len(l), l)
    return list(s)

Test Case

sample = ["apple", "orange", "banana", "grapes", "mango"]
uniqueCombinations(sample)

Output

[('apple', 'banana'),
 ('orange', 'mango'),
 ('orange', 'grapes'),
 ('apple', 'grapes'),
 ('orange', 'banana'),
 ('apple', 'mango'),
 ('grapes', 'mango'),
 ('apple', 'orange'),
 ('banana', 'mango'),
 ('banana', 'grapes')]

The input will be unique strings of list. Assume that duplicate elements will not be passed.

Is there a better / more elegant / more accurate way to do this??

\$\endgroup\$
9
  • \$\begingroup\$ uniqueCombinations(['apple', 'orange', 'apple']) returns [('orange', 'apple'), ('apple', 'apple'), ('apple', 'orange')]. Is this the output you are expecting for this case? \$\endgroup\$
    – Setris
    Mar 10, 2021 at 7:53
  • 1
    \$\begingroup\$ yes, the original list_elements can contains duplicates. \$\endgroup\$ Mar 10, 2021 at 8:00
  • \$\begingroup\$ When I run your code it does not produce that output. \$\endgroup\$
    – FMc
    Mar 10, 2021 at 8:26
  • \$\begingroup\$ The code in the question or in the answer?? \$\endgroup\$ Mar 10, 2021 at 8:34
  • \$\begingroup\$ Is the order of the tuple important? If you sort list_elements you get ('banana', 'orange') but lose ('orange', 'banana'). The challenge is poorly defined. If so why are you duplicating output with ['apple', 'orange', 'apple']? \$\endgroup\$
    – Peilonrayz
    Mar 10, 2021 at 10:22

1 Answer 1

4
\$\begingroup\$

From itertools.combinations, emphasis mine:

Return r length subsequences of elements from the input iterable.

The combination tuples are emitted in lexicographic ordering according to the order of the input iterable. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.

Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each combination.

Which means as long as we pass in a collection of unique elements to itertools.combinations, there will be no duplicate values in the combinations it returns. And if we can assume that the input list will not contain any duplicate elements, we can rewrite the function like so:

import itertools

def unique_combinations(elements: list[str]) -> list[tuple[str, str]]:
    """
    Precondition: `elements` does not contain duplicates.
    Postcondition: Returns unique combinations of length 2 from `elements`.

    >>> unique_combinations(["apple", "orange", "banana"])
    [("apple", "orange"), ("apple", "banana"), ("orange", "banana")]
    """
    return list(itertools.combinations(elements, 2))
\$\endgroup\$
9
  • \$\begingroup\$ @superbrain True, then in that case we'd need clarification from @Pluviophile on what assumptions can be made about list_elements. \$\endgroup\$
    – Setris
    Mar 10, 2021 at 7:47
  • \$\begingroup\$ Trying the above code, I'm getting TypeError: 'type' object is not subscriptable \$\endgroup\$ Mar 10, 2021 at 10:15
  • \$\begingroup\$ Is that becoz of this part : list[str] -> list[tuple[str, str]]?? \$\endgroup\$ Mar 10, 2021 at 10:16
  • \$\begingroup\$ @Pluviophile sounds like you're not running Python 3.9, you can either omit those type hints or use from typing import List, Tuple -> List[str] List[Tuple[str, str]] \$\endgroup\$
    – Setris
    Mar 10, 2021 at 10:17
  • 1
    \$\begingroup\$ @superbrain I think the output for ['apple', 'orange', 'apple'] is actually a bug not a feature, with the OP's code. Check here, what do you think? \$\endgroup\$
    – Peilonrayz
    Mar 10, 2021 at 10:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.