Chris Hill
Chris Hill

Reputation: 33

"TypeError: unhashable type: 'list'" yet I'm trying to only slice the value of the list, not use the list itself

I've been having issues trying to create a dictionary by using the values from a list.

alphabetList = list(string.ascii_lowercase)
alphabetList.append(list(string.ascii_lowercase))
alphabetDict = {}
def makeAlphabetDict (Dict, x):
    count = 0
    while count <= len(alphabetList):
        item1 = x[(count + (len(alphabetList) / 2))]
        item2 = item1
        Dict[item1] = item2
        count += 1
makeAlphabetDict(alphabetDict , alphabetList)

Which returns:

TypeError: unhashable type: 'list'

I tried here and other similar questions yet I still can't see why Python thinks I'm trying to use the list, rather than just a slice from a list.

Upvotes: 0

Views: 1791

Answers (2)

thiruvenkadam
thiruvenkadam

Reputation: 4250

As Martijn Pieters noted, you have problem with the list append that adds a list within your other list. You can add two list in any of the following ways for simplicity:

alphabetList = list(string.ascii_lowercase)
alphabetList += list(string.ascii_lowercase)
# Adds two lists; same as that of alphabetList.extend(alphabetList)

alphabetList = list(string.ascii_lowercase) * 2
# Just for your use case to iterate twice over the alphabets

In either case, your alphabetDict will have only 26 alphabets and not 52 as you cannot have repeated keys within the dict.

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1121834

Your list contains a nested list:

alphabetList.append(list(string.ascii_lowercase))

You now have a list with ['a', 'b', ..., 'z', ['a', 'b', ..., 'z']]. It is that last element in the outer list that causes your problem.

You'd normally would use list.extend() to add additional elements:

alphabetList.extend(string.ascii_lowercase)

You are using string.ascii_lowercase twice there; perhaps you meant to use ascii_uppercase for one of those strings instead? Even so, your code always uses the same character for both key and value so it wouldn't really matter here.

If you are trying to map lowercase to uppercase or vice-versa, just use zip() and dict():

alphabetDict = dict(zip(string.ascii_lowercase, string.ascii_uppercase))

where zip() produces pairs of characters, and dict() takes those pairs as key-value pairs. The above produces a dictionary mapping lowercase ASCII characters to uppercase:

>>> import string
>>> dict(zip(string.ascii_lowercase, string.ascii_uppercase))
{'u': 'U', 'v': 'V', 'o': 'O', 'k': 'K', 'n': 'N', 'm': 'M', 't': 'T', 'l': 'L', 'h': 'H', 'e': 'E', 'p': 'P', 'i': 'I', 'b': 'B', 'x': 'X', 'q': 'Q', 'g': 'G', 'd': 'D', 'r': 'R', 'z': 'Z', 'c': 'C', 'w': 'W', 'a': 'A', 'y': 'Y', 'j': 'J', 'f': 'F', 's': 'S'}

Upvotes: 4

Related Questions