unsupported operand type(s) for *: 'map' and 'float'

Viewed 272

I'm working on a python3 lab that requires me to write a python code that generates datapoints. There also needs to be at least 200 different points for each line. Use sizes like 10000.

However, I keep getting an error stating that "unsupported operand type(s) for *: 'map' and 'float'" caused by the underlined portion of code below. I understand that numpy doesn't work with map() on python3 and that I'll have to change "total_steps" into a list but I haven't been able to find a solution that works.

#!/usr/local/python3

import random
import matplotlib.pyplot as plt
import numpy as np
from decimal import Decimal

def partition(arr, low, high): 
    i = (low-1)   
    pivot = arr[high] 
  
    for j in range(low, high): 
        if arr[j] <= pivot: 
            i = i+1
            arr[i], arr[j] = arr[j], arr[i] 
  
    arr[i+1], arr[high] = arr[high], arr[i+1] 
    return (i+1) 
  
def quickSort(arr, low, high, step): 
    if len(arr) == 1: 
        return step
    if low < high: 
        pi = partition(arr, low, high) 
  
        step += quickSort(arr, low, pi-1, step)
        step += quickSort(arr, pi+1, high, step)
        step += 1
    
    return step

def gen(size):
    return [random.randrange(10000) for i in range(size)]

def to_decimal(l):
    return [Decimal(i) for i in l]


sizes = sorted(random.sample(range(200, 10001), 20))
print(sizes)
total_steps = []
for size in sizes:
    datapoints = gen(size)
    total_steps.append(quickSort(datapoints, 0, size-1, 0))

print(total_steps)
fig = plt.figure()
ax = plt.axes()

sizes = np.array(sizes)/10000

total_steps = np.array(map(Decimal,total_steps))*0.00001
--------------------------------------------------------


plt.plot(sizes, to_decimal(total_steps))
plt.show()

2 Answers

map returns a map object. You are getting this error because you are trying to multiply an array containing a single map object by a float.

You should coerce it to a list so the array is created with a compatible type:

total_steps = np.array(list(map(Decimal,total_steps))) * Decimal(0.00001)

Alternatively, you can use np.fromiter:

total_steps = np.fromiter(map(Decimal,total_steps), float) * Decimal(0.00001)

You need to learn a little more debugging. Work through your objects:

>>> map(Decimal,total_steps)
<map object at 0x0000028E0938D940>
>>> np.array(map(Decimal,total_steps))
array(<map object at 0x0000028E0938D748>, dtype=object)
>>> np.array(list(map(Decimal,total_steps)))
array([Decimal('620'), Decimal('1239'), Decimal('2003'), Decimal('2059'),
       Decimal('2326'), Decimal('2444'), Decimal('2607'), Decimal('4053'),
       Decimal('4093'), Decimal('4275'), Decimal('4364'), Decimal('4873'),
       Decimal('6015'), Decimal('6680'), Decimal('6740'), Decimal('8155'),
       Decimal('8288'), Decimal('8523'), Decimal('9145'), Decimal('9637')],
      dtype=object)

You originally made a NumPy array with a single element, a map object -- an iterator, not the result of the iteration. To get the result, you need to force the iteration, such as with the list constructor. Even then, you have an array of Decimal objects. You cannot multiply that by a float. You need to convert them to compatible types. For instance,

np.array(list(map(Decimal,total_steps))) * Decimal(0.00001)
Related