Home > Enterprise >  unhashable type: 'list' when creating a combination function with Python
unhashable type: 'list' when creating a combination function with Python

Time:01-05

I'm currently trying to create a combination function that has the equal function to the itertools.combinations.

The following code is the code that I am working on:

def my_combs(s, num):
    if num == 0:
        return [[]]
    res = []
    for i in range(0, len(s)):
        m = s[i]
        rems = s[i   1:]
        for p in my_combs(rems, num-1):
            res.append([m] p)
    return res

from itertools import combinations
test = [1, 2, 3, 4]
print(set(combinations(test, 2)))
print(set(my_combs(test, 2)))

The result I want to get is

{(1, 2), (1, 3), (1, 4), (2, 3), (3, 4), (2, 4)}

But I keep getting an error that says unhashable type: 'list'


And then, when I change the print(set(my_combs(test, 2))) to print(my_combs(test, 2)), I get

[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] 


While the elements of the results seem to be the same,
I want to get the results in tuples (i.e { ( ) } ), instead of lists (i.e [ [ ] ]).

Is there any way for me to solve the error and get the results I want with the condition of unchanging any of the print statements?
(i.e I want to have the print statement as print(set(my_combs(test, 2))) and change only the my_combs() function)

CodePudding user response:

If you want tuples instead of lists - just use tuples instead of lists :)

def my_combinations(s, num):
    if num == 0:
        return [()]                              # HERE
    res = []
    for i in range(0, len(s)):
        m = s[i]
        rems = s[i   1:]
        for p in my_combinations(rems, num-1):
            res.append((m,) p)                   # HERE
    return res

from itertools import combinations
test = [1, 2, 3, 4]
print(set(combinations(test, 2)))
print(set(my_combinations(test, 2)))

Note that one-element tuple has to have a comma in it: (m,); without it, (m), it is just something in parentheses.

CodePudding user response:

Item in set should be hashable. List is mutable, Tuple is hashable, So change list to tuple.

Change last line to :

print(set(tuple(item) for item in my_combinations(test, 2)))

CodePudding user response:

You can change the local variable res into a tuple and add tuples to it recursively by changing res.append([m] p) to res = res ((m,) p,):

def my_combinations(s, num):
    if num == 0:
        return (tuple(),)
    res = tuple()
    for i in range(0, len(s)):
        m = s[i]
        rems = s[i   1:]
        for p in my_combinations(rems, num-1):
            res = res   ((m,) p,)
    return res

from itertools import combinations
test = [1, 2, 3, 4]
assert set(combinations(test, 2)) == set(my_combinations(test, 2))
  •  Tags:  
  • Related