How To Fix TypeError: unhashable type ‘slice’

Estimated reading time: 2 minutes

So you have a Python dictionary, and you want to retrieve data from it and print it to a screen. There are some characteristics of Python that first of all should be understood:

  1. They are mutable
  2. They also have the ability to grow and shrink as required.
  3. Data is accessed within the dictionary via keys.

The last point is very important as dictionaries do not have an index value, and this is why you get the TypeError you are here to solve for.

So let us recreate the problem

In the below code we have a dictionary called “userdata”, with its key-value pairs.

The loop is trying to retrieve the index value 1 for all the values in dai_data.

As can be seen, dai_data is trying to retrieve the last three index values within the dictionary.

As noted above the only way to access dictionary values is through their key values.

userdata = {
	  "name": "Data Analytics Ireland",
	  "Country": "Ireland",
	  "City": "Dublin",
	  "Age": "1000 years!",
}

dai_data = userdata[:3]

for i in dai_data:
	     print(i[1])

Output:
Traceback (most recent call last):
  File "", line 8, in <module>
    dai_data = userdata[:3]
TypeError: unhashable type: 'slice'

So how do we fix this problem?

First of all, values are accessed through the key within the dictionary

In the below dictionary the key values are: Name, Country, City, Age

userdata = {
	  "Name": "Data Analytics Ireland",
	  "Country": "Ireland",
	  "City": "Dublin",
	  "Age": "1000 years!",
}

print(userdata["Name"])
print(userdata["Country"])
print(userdata["City"])
print(userdata["Age"])

Output:
Data Analytics Ireland
Ireland
Dublin
1000 years!

As a result, now we are able to access the values associated with each key.

Did you know you could add a list to one of your key-value pairs?

In the above example, we focused on a single value, but we could also make a key equal to a list.

userdata = {
	  "Name": ["Joe","Jim"],
	  "Country": "Ireland",
	  "City": ["Dublin","Cork","Limerick"],
	  "Age": "1000 years!"
}

print(userdata["Name"])
print(userdata["Country"])
print(userdata["City"])
print(userdata["Age"])

Output:
['Joe', 'Jim']
Ireland
['Dublin', 'Cork', 'Limerick']
1000 years!

TypeError: Array() Argument 1 Must Be A Unicode Character, Not List

In a recent post, we discussed arrays and what they mean and how they differ from lists. When you have a list in an array, one of the things that you need to define is what data type it is. If you don’t then the array will throw the error that you are on this page to resolve.

On the Python.org website, below are the list of values that can be populated to indicate what the data type of a list is in an array.

If you don’t add in the value you will get the below error:

ValueError: bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)

Let’s look at an example

import array as test_array

a = test_array.array([1,2,3])

print(a)

Gives an error of:
TypeError: array() argument 1 must be a unicode character, not list

As can be seen, the above logic tries to print a list within an array. The problem here is that an array can only be of one data type, and it has to be specified on the array creation.

How do we fix this?

It is quite simple! Before the list, we simply specify which type code we would like to apply from the above list. In this instance we are going to assign it as “signed int” that being the value “i” as follows:

import array as test_array

a = test_array.array("i",[1,2,3])

print(a)

Prints the following with no error:
array('i', [1, 2, 3])

Process finished with exit code 0

I can change the value “i” to any of the values I want from the above list, just picked that one to show as an example.

TypeError: List Indices Must Be Integers Or Slices, Not Tuple

Estimated reading time: 3 minutes

When working with Python lists in your data analytics projects, when you trying to read the data, a common problem occurs if you have a list of lists, and it is not properly formatted.

In this instance, Python will not be able to read one or more lists and as a result, will throw this error.

In order to understand how this problem occurs, we need to understand how to create a list of lists.

How to create a lists of lists

Let’s look at a simple list:

a = [1,2,3]
print(a)
print(type(a))

Result:
[1, 2, 3]
<class 'list'>

Let’s create a second list called b:

b = [4,5,6]
print(b)
print(type(b))

Result:
[4, 5, 6]
<class 'list'>

So if we want to join the lists together into one list ( hence a list of lists) then:

a = [1,2,3]
b = [4,5,6]

list_of_lists = []
list_of_lists.append(a)
list_of_lists.append(b)
print(list_of_lists)
print(type(list_of_lists))

Result:
[[1, 2, 3], [4, 5, 6]]
<class 'list'>

So as can be seen the two lists are contained within a master list called “list_of_lists”.

So why does the error list indices must be integers or slices, not tuple occur?

Reason 1 ( Missing commas between lists)

If you manually type them in and forget the comma between the lists this will cause your problem:

a=[[1,2,3][4,5,6]]
print(a)

Result (Error):
Traceback (most recent call last):
  line 10, in <module>
    a=[[1,2,3][4,5,6]]
TypeError: list indices must be integers or slices, not tuple

But if you put a comma between the two lists then it returns no error:

a=[[1,2,3],[4,5,6]]
print(a)

Result (no error):
[[1, 2, 3], [4, 5, 6]]
Process finished with exit code 0

Reason 2 ( Comma in the wrong place)

Sometimes you have a list, and you only want to bring back some elements of the list, but not others:

In the below, we are trying to bring back the first two elements of the list.

a= [1,2,3,4,5]
print(a[0:,2])

Result:
Traceback (most recent call last):
   line 14, in <module>
    print(a[0:,2])
TypeError: list indices must be integers or slices, not tuple

The reason that the same error happens is the additional comma in a[0:,2], causes the error to appear as Python does not know how to process it.

This is easily fixed by removing the additional comma as follows:

a= [1,2,3,4,5]
print(a[0:2])

Result:
[1, 2]
Process finished with exit code 0

So why is there a mention of tuples in the error output?

The final piece of the jigsaw needs to understand why there is a reference to a tuple in the error output?

If we return to a looking at a list of lists and look at their index values:

a=[[1,2,3],[4,5,6]]
z = [index for index, value in enumerate(a)]
print(z)

Result:
[0, 1]
Process finished with exit code 0

As can be seen, the index values are 0,1, which is correct.

As before removing the comma gives the error we are trying to solve for:

a=[[1,2,3][4,5,6]]
z = [index for index, value in enumerate(a)]
print(z)

Result:
Traceback (most recent call last):
  line 16, in <module>
    a=[[1,2,3][4,5,6]]
TypeError: list indices must be integers or slices, not tuple

BUT the reference to the tuple comes from the fact that when you pass two arguments (say an index value) a Tuple is created, but in this instance, as the comma is missing the tuple is not created and the error is called.

This stems from the __getitem__ for a list built-in class cannot deal with tuple arguments that are not integers ( i.e. 0,1 like we have returned here) , so the error is thrown, it is looking for the two index values to pass into a tuple.

TypeError: the first argument must be callable

Estimated reading time: 3 minutes

So you may be using Python Classes and have encountered the problem TypeError: First Argument Must be Callable. So what does the problem mean and how can you fix it?

In this article, we are looking to explain how it may occur and the easy fix you can apply to stop the problem in the future.

Let us understand calling Functions/Methods first

Normally in a computer python program, you will have a need to use a function/method as it has the functionality that will save you time, and can continuously be reused.

A classic example is print(“Hello”) that handles all the required logic to show this on a screen. Its output is quickly viewable, and there is not any need to understand what is going on in the background.

Here in this example we have run the function on its own, as a result it does not need to pointed to somehwhere else to run the logic it contains.

For the error we are looking to resolve, this is part of the problem. A function/method can be run on its own, or from within a Class.

The defining differene is that on its own it needs the parenthensis i.e. (), but if if you calling it from within a class, then it has to be handled differently.

Seeing the Type Error First Argument must be callable and fixing it

In the below we have a block of code, that produces the error we are trying to fix.

Following on from what was discussed above, the offending line is highlighted.

In particular the problem lies with printprogress() . This is been called , but in actual fact the problem is that when you have the logic written like this, it gives the error this blog post was setup for.

In essence it is trying to run the program from that exact point, which python does not allow.

Removing the parenthesis then allows the program to go and find the module it is referencing and then run the logic contained within that.

import schedule
import time

class scheduleprint():

    def printprogress(self):
        print("Start of Processing")
        print("Processing Complete")

    def schedule_a_print_job(self, type="Secs", interval=5):

        if type == "Secs": # Fed from the function paramaters
            schedule.every(interval).seconds.do(self.printprogress())===> The problem is here, remove the () after printprogress.
            # Including the parentheses  after printprogess will throw an error as you cant run that method directly from there you can only call it.

        if type == "Mins": # Fed from the function paramaters
            schedule.every(interval).minutes.do(self.printprogress)
            # Including the parentheses  after printprogess will throw an error as you cant run that method directly from there you can only call it.

        while True:
            schedule.run_pending()
            time.sleep(1) # The number of seconds the Python program should pause execution.

run = scheduleprint() # initiating an instance of the class "scheduleprint"
run.schedule_a_print_job() # running the function contained within the class.

In summary to help troubleshoot this problem:

(A) Check your code to see where it is calling a module within a class.

(B) Next make sure that in that call no parenthesis are present, otherwise it wont be able to find the module.

TypeError: ‘NoneType’ object is not iterable

Estimated reading time: 2 minutes

Have you wondered why you cant iterate over a NoneType but never had it properly explained? Read on as here we will fully explain the concept and how you can fix it.

So what is a NoneType anyway?

First of all, to understand a none type, you need to understand what none is.

None is essentially no value, so in other words, nothing is present. It differs from the integer zero, as the integer zero is an actual value and it exists.

If you were to put both of them side by side on a database table, one would be empty the other would have a value of zero.

Also, None is a type in itself:

a = None
print(a)
print(type(a))

Gives the output:

None
<class 'NoneType'>

Whereas zero is an integer datatype:

a = 0
print(a)
print(type(a))

Giving output:
0
<class 'int'>

So how does a none type object is not iterable occur?

Let’s take an example and walk through it. In the below code we have a variable that is empty. In other words, we are asking the program to loop through something that does not exist and does not have any values.

a = None
print(a)
print(type(a))

for i in a:
   print(i)

Giving output:
for i in a:
TypeError: 'NoneType' object is not iterable
None
<class 'NoneType'>

Repeating what we said above, it is not possible to loop through something that does not have a value.

But if we change it to a string value of ‘1’, the loop will work.

a = '1'
print(type(a))

for i in a:
   print(i)

So in summary:

(A) NoneTypes are useful if you just want to return an empty value or check for an empty value.

(B) You cannot loop over NoneTypes as they do not have any values, they are empty!

TypeError: ‘list’ object is not an iterator

We have covered off many TypeErrors on this website, here we will go through which using a list with and it is not an iterator gives you errors.

In order to understand this error better, we need to first understand what is an iterator in Python?

An iterator is a Python object that has the following characteristics:

  • You can count the no of values that are contained within it.
  • It also can be iterated through, so you need to apply an iteration method to it.

How does this error occur?

Normally this error occurs when you try to iterate over a list, but you have not made the list iterable.

There are two things required to make this happen:

(A) The iter() returns an iterator object

(B) The next() method moves to the next value.

Without both the code will fail and the error you are about will occur!

In the below code we have a list:

a = ['q', 'w', 'e', 'r', 't', 'y']

with the following:

b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)

As can be seen in the above code we have one component for the iteration , we expect two as per the above.

As a result we get the error:

Traceback (most recent call last):
  File "list_object_is_not_an_iterator.py", line 13, in <module>
    b = next(a)
TypeError: 'list' object is not an iterator

In order to fix this ,all we need to do is apply the iterator to the list as follows:

a = iter(['q', 'w', 'e', 'r', 't', 'y']) ====> We added in the iter() here, enclosing the list within it

b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)
#b = next(a)


print(b)

Giving output:
y

As a result of this, we now have the two required methods that will not give this error.

What is going on within the iterator?

In the above code we have asked to print b. What the iterator is doing is going to the first value of b, in this case q and print.

But because we have a variable b on multiple lines, with the method “next()” in it, the logic is moving through each value of the list till it gets to the end.

What can be done though is , reduce the length of the returned b variables to print as follows:

a = iter(['q', 'w', 'e', 'r', 't', 'y'])
b = next(a)
print(b)
returns:
q

BUT
a = iter(['q', 'w', 'e', 'r', 't', 'y'])
b = next(a)
b = next(a)
print(b)
returns:
w

As can be seen it returns the next value in the list. You can keep adding the b variables.

What happens when you get to the end of the list?

So now we have the below, and we are returning the last value:

a = iter(['q', 'w', 'e', 'r', 't', 'y'])
b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)

Returns:
y

The reason for this is that we have the required no of variables with the next method, which equals the length of the list.

If we add in one more b variable:

a = iter(['q', 'w', 'e', 'r', 't', 'y'])
b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a)
b = next(a) ===> Additional b variable

Returns: 
Traceback (most recent call last):
  File "list_object_is_not_an_iterator.py", line 19, in <module>
    b = next(a)
StopIteration

The purpose of StopIteration is to not allow a continuous loop and recognise that the end of the list has been reached.

Implementing Iterators

Iterators could be used in the following circumstances:

(A) You have a defined list of object values to work with.

(B) If sequence is important an iterator will help to process values in the order they appear in a list.

TypeError: ‘float’ object is not callable

So you have been presented with the TypeError: ‘float’ object is not callable in Python, but unsure how to fix? Well read on so we can get you a solution.

First things an overview of a Float

A float is any number that can contain a decimal place separating an integer from the fractions to the right of the decimal point.

As an example, in the below code, we have the exact same number. But when a computer comes to read it, it treats them differently, due to the fact that b has a decimal point and a fraction to the right of it.

a = 1
b = 1.0

print (type(a))
print (type(b))

Output:
<class 'int'>
<class 'float'>

So how in a piece of code would this error occur?

In the below code, the error occurs. The reason behind this is that float is an actual function that changes a value to a float data type.

As a result, you cannot assign a variable name as “float” and then call it separately in its code. Python specifically does not allow a programmer to use a function as a variable name.

a= float(10)
b= float(11)
c= float(12)
float = a

d = float(a/b*c)
print(d)

Output:
d = float(a/b*c)
TypeError: 'float' object is not callable

So how is this fixed?

In order to fix this, we rename the variable “float” to something else, and make sure that the new name is not another function name!

As can be seen when we do this, the below output runs as expected with no errors:

a= float(10)
b= float(11)
c= float(12)
float_value = a   ===> This line was corrected from above from "float" to "float_value"

d = float(a/b*c)
print(d)

Output: 
10.909090909090908

In summary the crux of this problem is that when creating a variable, it cannot be a function name.

You can see similar posts here on TypeErrors.

Have you seen these posts?

TypeError: ‘float’ object is not callable

TypeError: ‘int’ object is not callable

TypeError: ‘int’ object is not callable

Estimated reading time: 1 minute

We have posted several python solutions to TypeErrors here on the website. Here is another one we hope you will find useful in solving a programming issue you may have.

So what does the error mean?

In the below code, we have four variables that have been assigned an integer.

a= 10
b= 11
c= 12
int= 13

d = int(a/b*c)
print(d)

As can be seen we also have a variable d that is assigned to a function int , that is using the variables a,b,c.

As int is a function it cannot be assigned as a variable, and for this reason the below error will appear:

d = int(a/b*c)
TypeError: 'int' object is not callable

So how can this be fixed?

The solution to this is quite straight forward, it is important not to assign a function as a variable. The fix you would apply is as follows:

Incorrect code:

a= 10
b= 11
c= 12
int = 13  ===> change this line to fix the error

d = float(a/b*c)
print(d)

Corrected code:
a= 10
b= 11
c= 12
int_value = 13  ===> corrected line of code
d = float(a/b*c)
print(d)

Giving you the result:
10

As can also be seen with TypeError: ‘str’ object is not callable assign variables to functions should be avoided at all cost.

TypeError: ‘str’ object is not callable

Estimated reading time: 2 minutes

This is a common TypeError that you will come across in Python, it is actually easy to diagnose how it occurred.

To start off we need to understand “str” is a function in python, and it converts any value into a string.

As a result , because it is a function your ability to call it has limitations.

So in essence it has parenthesis () beside it, and allows parameters to be passed to it.

So lets first look at how the string function works:

x = str("10")
y = 10

print(type(x))
print(type(y))
print(x)
print(y)

With output:
<class 'str'>
<class 'int'>
10
10

As you will see the above the value 10, on its own is an integer, but when you call the string function, it now becomes a string.

For this reason this , calling a string function , completes a conversion to string of ten, but what if the variable is called str?

Lets take an example below from an input:

str = input("what year where you born?")
print(str(str))

Output:

what year where you born?2021
Traceback (most recent call last):
  File "str obj is not callable.py", line 2, in <module>
    print(str(str))
TypeError: 'str' object is not callable

Process finished with exit code 1

The reason for this error above , is that we have named the variable “str”.

As can be seen the programme is trying to use the first str in the print statement as a function.

As we know by now string variables are not callable.

Accordingly the function str() which the programme is trying to run, fails with the TypeError identified.

For this reason to fix this problem we would change the variable called str to “year”, the error then disappears.

The updated code will work as when calling str(), it is not conflicted with a variable name.

year = input("what year where you born?")
print(str(year))

Output:
"str obj is not callable.py"
what year where you born?2021
2021

Process finished with exit code 0

So to summarise:

  • Strings are not callable
  • Don’t name a variable as str, or any function name, these are reserved words by the system.
  • Functions are callable, strings are not.

TypeError: cannot unpack non-iterable int object

Often when working on a data analytics project it requires you to split data out into its constituent parts.

There are a number of reasons for this, it can be confusing when you get errors as with the title of this post.

Before we explain this error and what it means, lets us first explain unpacking

Unpacking basically means splitting something up into a number of its parts that make it up.

To demonstrate if you take a,b,c = 123, and look to unpack it, it throws out the error, but why?

Well pure and simple, we have three values on the left “a,b,c”, looking for three values on the right.

a,b,c = 123
print(a)

Output:
 a,b,c = 123
TypeError: cannot unpack non-iterable int object

If you would like to fix this problem change the right hand side to have three values.

a,b,c = 1,2,3
print(a)
print(b)
print(c)
print(a,b,c)

Output:
1
2
3
1 2 3

Process finished with exit code 0

In essence, what is going on is that an evaluation checking that both sides have the same amount of values.

It is important to remember, the code above we used to show the error is an integer, which cannot be unpacked.

So if you take 123 for an example, which we used here it cannot be split into say 100 and 10 and 13.

In this case, even though when they are added up to 123, integers cannot be unpacked.

For this reason in the code for our solution, the difference is that the values used are tuples as follows:

a,b,c = 1,2,3
print(a)
print(b)
print(c)
print(a,b,c)
print(type((a,b,c)))

Or 
a,b,c = (1,2,3)
print(a)
print(b)
print(c)
print(a,b,c)
print(type((a,b,c)))

yield the same result:

1
2
3
1 2 3
<class 'tuple'>

Process finished with exit code 0

So in summary:

When unpacking there are a number of things to remember:

  • Integers on their own cannot be unpacked.
  • You need to make sure that if you have a number of variables, that you have the same number of integers if they the values.
    • This will make it a tuple and unpacking can then happen.