Python Index error using generator with yield - python

I'm running this code and I get the values I want from it, but there is also an IndexError: tuple index out of range for lines 12 and 18
import statistics as st
def squares(*args):
i = 0
val = []
fin = []
val = args
while True:
avg = (st.mean(val))
fin = (avg - val[i]) ** 2 # line 12
yield fin
i += 1
mylist = squares(3, 4, 5)
for x in mylist: # line 18
print(x)
result:
1
0
1
Traceback (most recent call last):
File line 18, in <module>
for x in mylist:
File line 12, in squares
fin = (avg - val[i]) ** 2
IndexError: tuple index out of range

Base on your code there are some variables & methods that you did that I think you can also change. Like example on this one. I commented out your old code so you can see the changes & difference.
import statistics as st
def squares(*args):
#i = 0
#val = []
fin = []
val = args
for n in val:
avg = (st.mean(val))
fin = (avg - n) ** 2 # line 12, #val[i]
#i += 1
yield fin
mylist = squares(3, 4, 5)
for x in mylist: # line 18
print(x)
I can see here that you are trying to access every value of val with fin = (avg - val[i]) ** But you can also use a for loop with it & don't need for a i variable as index. Also what #schwobaseggl is correct, you get the error IndexError: tuple index out of range because you kept incrementing or adding up your i to the point where you are trying to access a value from your val variable that is beyond its length.

You can simplify the generator function:
import statistics as st
def squares(*args):
avg = st.mean(args)
for arg in args:
yield (avg - arg) ** 2
Note that in your original, you have an infinite loop (while True) that you never break and that keeps incrementing index i while the i-accessed sequence val does not grow. That was always an IndexError waiting to happen.

Related

String index out of range, solution is working fine

I'm trying to change all the characters to the symbol "#" except the last 4. The error I get:
> Traceback (most recent call last):
File "tests.py", line 16, in
> <module>
> r = maskify(cc) File "/workspace/default/solution.py", line 19, in maskify
> n[i] = c[i] IndexError: string index out of range
The code
c = "3656013700"
cc = list(c)
a = (len(cc)-1) - 4
b = []
def maskify(cc):
n = list(len(cc) * "#")
while len(cc) <= 4:
return str(cc)
break
else:
for i in range(len(cc)):
if i <= a:
n[i] = n[i]
else:
n[i] = c[i]
b = "".join([str(i) for i in n])
return b
maskify(cc)
I don't know why you're complicating it. As #blorgon has already pointed it out, you can directly return it in one line. Further simplifying it, you don't need even need to convert the string into a list. Just directly pass the string as argument.
c = "3656013700"
def maskify(c):
return (len(c) - 4) * "#" + c[-4:]
print(maskify(c))
If this is not what you're trying to achieve, your question is unclear.
You are going through a complicated route. Here is another approach:
c = "3656013700"
def maskify(cc):
return cc.replace(cc[:-4], '#'*(len(cc)-4))
print (maskify(c))
Output:
######3700
If you want to go with the iterative approach you can simplify the code substantially:
def maskify(c):
# Check if lenght of string is 4 or less
if len(c) <= 4:
return c
else:
# string into a list
cc = list(c)
# Iterate over the list - 4 last items
for i in range(len(c)-4):
cc[i] = "#"
return "".join(cc)
s = "3656013700"
s = maskify(s)
print(s)

'TypeError: 'NoneType' object is not subscriptable' about lists

what does this error mean?
this is my code:
import csv
from statistics import mean
averages = list()
sorted_averages = list()
dic = dict()
with open('first.csv') as fopen:
reader = csv.reader(fopen)
for line in reader:
name = line[0]
line = line[1:]
counter = 0
for i in line:
i = float(i)
line[counter] = i
counter += 1
average = mean(line)
averages.append(average)
dic[name] = average
for i in range(0, len(averages)):
maxi = 0
maxi1 = 0
for number in averages:
if number > maxi:
maxi = number
elif number == maxi:
maxi = number
maxi1 = number
else:
maxi = maxi
sorted_averages.append(maxi)
averages.remove(maxi)
del(averages)
insorted_averages = sorted_averages.reverse()
for z in insorted_averages[:3]:
print(z)
i have sorted my list from max to min. Now i want to print 3 worth averages but i got that error. i have done with with changing 3 to -4 but it didnt work too
.reverse() reverses your list in-place and returns None:
sorted_averages = list(range(3))
insorted_averages = sorted_averages.reverse()
print(insorted_averages)
insorted_averages is now None. sorted_averages is reversed though...
read (4) in the python doc under mutable sequence types.

I'm getting index out of list Error [duplicate]

This question already has answers here:
Does "IndexError: list index out of range" when trying to access the N'th item mean that my list has less than N items?
(7 answers)
Closed 5 years ago.
def calcDistance(x1, y1, x2, y2):
distance = sqrt((x1-x2)**2 + (y1-y2)**2)
return distance
def make_dict():
return defaultdict(make_dict)
# Capture 1 input from the command line.
# NOTE: sys.argv[0] is the name of the python file
# Try "print sys.argv" (without the quotes) to see the sys.argv list
# 1 input --> the sys.argv list should have 2 elements.
if (len(sys.argv) == 2):
print "\tOK. 1 command line argument was passed."
# Now, we'll store the command line inputs to variables
myFile = str(sys.argv[1])
else:
print 'ERROR: You passed', len(sys.argv)-1, 'input parameters.'
quit()
# Create an empty list:
cities = []
# Create an empty dictionary to hold our (x,y) coordinate info:
myCoordinates = {}
# Open our file:
myFile = '%s.csv' % (myFile)
with open(myFile, 'rb') as csvfile:
spamreader = csv.reader(csvfile, delimiter=',', quotechar='|')
for row in spamreader:
# Only read rows that do NOT start with the "%" character.
if (row[0][0] != '%'):
# print row
id = int(row[0])
isHome = int(row[1])
x = float(row[2])
y = float(row[3])
myCoordinates[id] = {'x': x, 'y': y}
# print myCoordinates[id]['x']
# print myCoordinates[id]['y']
if (isHome == 1):
# Store this id as the home city
homeCity = id
cities.append(id)
print homeCity
print cities
# Create a TSP tour.
# VERSION 1 -- Using range() and for() loops:
myTour = []
for i in range(homeCity, len(cities)+1):
myTour.append(i)
for i in range(1, homeCity+1):
myTour.append(i)
print myTour
# VERSION 2 -- Using only range()
'''
firstPart = range(homeCity, len(cities)+1)
secondPart = range(1, homeCity+1)
myTour = firstPart + secondPart
print myTour
'''
tau = defaultdict(make_dict)
for i in cities:
# print "distance[%d][%d] = 0" % (i, i)
tau[i][i] = 0
for j in range(i+1, len(cities)+1):
# print "distance[%d][%d] > 0" % (i, j)
tau[i][j] = calcDistance(myCoordinates[i]['x'], myCoordinates[i]['y'], myCoordinates[j]['x'], myCoordinates[j]['y'])
# print "distance[%d][%d] = distance[%d][%d]" % (j, i, i, j)
tau[j][i] = tau[i][j]
# FIXME -- Edit the code below...
# Calculate the total distance of our TSP solution:
i = myTour[i]
for myIndex in range(1, len(myTour)+1):
j = myTour[myIndex]
print j
Function to calculate cost based on distance. Need to be modified.
def cost(rate,j):
cost = rate * j
cost = cost(1000,j)
print cost
Also I need to calculate cost based on distance traveled. with myIndex i am getting an error of list index out of range. I am not knowing what exactly is going there. The j is like total distance calculated.
List in python have 0 based index. If you add n elements to a list the indexes are from 0 to n-1. But you are running the loop from 1 to n. So, it getting list index out of range error.
You should do this-
for myIndex in range(0, len(myTour)):
j = myTour[myIndex]
print(j)
If you are getting list index out of range error then change the loop where you are getting the error and accessing a list using 1-based indexing, from range(1,len(some_list)+1) to range(0,len(some_list)). Or you can simply write range(len(some_list)). When there is no start value passed in the range function it starts from 0 by default.
To calculate cost try this -
for myIndex in range(0, len(myTour)):
j = myTour[myIndex]
cost = rate * j
print(cost)
Set the value of rate before starting the loop.

Unbroken chain? Python iteration not being processed

So I've written a bit of code to stack integers in a list from the zeroth position. For some reason I cannot decipher, the while loop below is not being processed. I have followed all good style and syntax requirements that I know, and the while loop works when run by itself.
def row(line):
"""
Function that merges a single row or column.
"""
result_length = len(line)
print result_length
# Create a list of zeros the same length as the 'line' argument
pts_alloc = 0
dummy = 0
result = line
result[0:] = [pts_alloc for dummy in range(len(result))]
print result
#Iterate over the 'line' list looking for non-zero entries and
#stack them from 'result[0]'
line_count = 0
result_place = 0
while (line_count <= (len(line)-1)):
if (line[line_count] > 0):
result[result_place] = line[line_count]
print result
result_place += 1
line_count += 1
return result
print row([4, 0, 0, 5])
Is there a major error in this code that I've missed? Is there some syntax requirement that I am unaware of?
The problems seems to be this part:
result = line
result[0:] = [pts_alloc for dummy in range(len(result))]
By replacing a slice of result, with result = line, you are replacing that same slice in line, too, as result is just another reference to the same list, not a copy.
Since the slice is the entire list, anyway, just do:
result = [pts_alloc for dummy in range(len(result))]
Also, you are declaring a lot of unnecessary variables. You could shorten your code to this:
def row(line):
result = [0] * len(line)
result_place = 0
for x in line:
if x > 0:
result[result_place] = x
result_place += 1
return result
Or even this:
def row(line):
non_zero = [x for x in line if x > 0] # take non-zero values
return non_zero + [0] * (len(line) - len(non_zero)) # pad with zeros

Python list index error in an if statement

I am not sure why I am getting this list index out of bounds error
Basically what is supposed to happen is I am sending my def a list of twitter userIds and then breaking them into chunks of 100 looking them up in twitter, then adding them to a dictionary using the userIds as the key. So lets say 00001 is johnny we look up 00001 get johnny and then make a dictionary with 00001, johnny. However the if statements don't seem to trigger.
Here is the code:
def getUserName(lookupIds):
l = len(lookupIds) # length of list to process
i = 0 #setting up increment for while loop
screenNames = {}#output dictionary
count = 0 #count of total numbers processed
print lookupIds
while i < l:
toGet = []
if l - count > 100:#blocks off in chunks of 100
for m in range (0,100):
toGet[m] = lookupIds[count]
count = count + 1
print toGet
else:#handles the remainder
r = l - count
print screenNames
for k in range (0,r):#takes the remainder of the numbers
toGet[k] = lookupIds[count]
count = count + 1
i = l # kills loop
screenNames.update(zip(toGet, api.lookup_users(user_ids=toGet)))
#creates a dictionary screenNames{user_Ids, screen_Names}
#This logic structure breaks up the list of numbers in chunks of 100 or their
#Remainder and addes them into a dictionary with their userID number as the
#index value Count is for monitoring how far the loop has been progressing.
print len(screenNames) + 'screen names correlated'
return screenNames
The error is as follows:
Traceback (most recent call last):
File "twitterBot2.py", line 78, in <module>
toPrint = getUserName(followingids)#Testing Only
File "twitterBot2.py", line 42, in getUserName
toGet[k] = lookupIds[count]
IndexError: list assignment index out of range
toGet is initialized to the empty list, and you're attempting to assign [0] a value. This is illegal. Use append instead:
toGet.append(lookupIds[count])
This is likely because you're attempting to lookup index zero when it doesn't exist. Example:
>>> x=[]
>>> x[0] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
def getUserName(lookUpIds):
blockSize = 100
screenNames = {}
indexes = xrange(0, len(lookUpIds), blockSize)
blocks = [lookUpIds[i:(i + blockSize)] for i in indexes]
for block in blocks:
users = api.lookup_users(user_ids=block)
screenNames.update(zip(block, users))
return screenNames

Categories