Question

[Solved] Python: TypeError: unhashable type: ‘slice’

I am reading CSV using python, here is the code.

train_csv = open('train.csv')
test_csv = open('test.csv')
train_data_reader = csv.DictReader(train_csv)
test_data_reader = csv.DictReader(test_csv)

row=[]
for row in train_data_reader:
    X.append([int(item) for item in row[4:]]) 
    char = row[1]
    Y.append(charIntConversion(char))
    train_id.append(row[0])
    prediction.append(row[1])
for row in test_data_reader:
    test_id.append(row[0])
    test_X.append([int(item) for item in row[4:]]

when I tried to run the code, it shows that TypeError: unhashable type: ‘slice’ for

X.append([int(item) for item in row[4:]])
test_X.append([int(item) for item in row[4:]] 

X and test_X should contain the value from column 4 to last column of the CSV.

May I know what’s wrong with my code and how can I fix this issue?

Solution #1:

I can see you have resolved your issue, but I thought I’d leave an answer here for any future readers. Who might get caught by this (I just was).

The issue is that the object is a dictionary and you are trying to pass it a slice, which is not hashable and hence cant be used as a dict key.

Simple example

>>> d = {0: 5, 1: 6, 2: 7, 3: 8, 4: 9}
>>> d[:5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'slice'

What you are trying to do is take n items from the collection. So the way to achieve this is to first convert the dict to a list (which is sliceable). To do this use dict.items, dict.keys or dict.values depending on your use case.

A dict (recent python 3.6 development notwithstanding) is not ordered and so what you will get back from dict.items (or friends) may not be in an order useful to you. So you can sort it before making the slice.

>>> sorted(d.items())[:5]
[(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]

The above code is slightly ugly, but works.

You could avoid the indexing by using islice from itertools

>>> from itertools import islice
>>> list(islice(sorted(d.items()), 5))
[(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]

You’d provide a key to sort if the default sorting order was not what you wanted. This way is inefficient as it sorts the entire collection before slicing, not sure of a way around that though.

Anyone arriving at this page and being puzzled by the above error, will not have realised they are attempting a slice on a dictionary. Performing a slice on a dictionary, doesn’t really make a lot of sense and most experienced developers would realise that if you do that you are asking for an unpredictable result.

If you genuinely do want to take the first n elements from a dictionary, say a row from a csv file where the columns are in some prescribed order. It would be much better to format the required keys into a tuple and just take those elements from the dict.

e.g.

To take only the first two columns from the dict

people = [{'name': 'paul', 'job': 'programmer', 'age': 'old'}, 
          {'name': 'chris', 'job': 'student', 'age': 'young'}]

>>> for p in people:
...     res = [p[key] for key in ('name', 'job')]
...     print(res)
['paul', 'programmer']
['chris', 'student']

hth

Respondent: Paul Rooney

Solution #2:

Encoder Example for Multiple Linear Regression Model

# Importing the dataset
dataset = pd.read_csv('Data.csv')
X = dataset.iloc[:, 0:4].values
y = dataset.iloc[:,4].values

# Encoding categorical data
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
labelencoder_X = LabelEncoder()
X[:, 3] = labelencoder_X.fit_transform(X[:, 3])
onehotencoder = OneHotEncoder(categorical_features = [3])
X = onehotencoder.fit_transform(X).toarray()
Respondent: user2515138

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Most Popular

To Top
India and Pakistan’s steroid-soaked rhetoric over Kashmir will come back to haunt them both clenbuterol australia bossier man pleads guilty for leadership role in anabolic steriod distribution conspiracy