Python Key Error can't parse fields - python

I'm writing a script and iterating over a list to turn it into a JSON. My code:
Mbody is the name of the list I'm pulling info from.
index = 38
payload = {}
i = 0
while i < Number_SKUs:
SKU_size = 2
size_index = 4
value_index = 1
time_index = 4
ms_index = 2
payload[i].sku = Mbody[index:(index + SKU_size*2)]
index = index + SKU_size*2
print(payload[i].sku)
i+=1
For some reason, this is resulting in
Traceback (most recent call last):
File "parser.py", line 101, in <module> payload[i].sku = Mbody[index:(index + SKU_size*2)]
KeyError: 0
I have searched on stack exchange and found several similar questions, but none of which answer mine. What's the best way to iterate over a list and parse the skus? This will become a JSON eventually, but I could work with it in an array for the time being and use a dict to put it into a JSON later.

In python you have to name the keys of a dictionary to interact with them.
p['a']['b']
# This is element b of p['a']
p['a'].b
# This is function b in object p['a']
Dotted notation is not available by default although some people have solutions to add that.
Ignoring those, we can make some changes to your code to start working with the usual notation.
index = 38
# This can just be a list, because i is continuous between 0 and Number_SKUs
payload = []
i = 0
while i < Number_SKUs:
SKU_size = 2
size_index = 4
value_index = 1
time_index = 4
ms_index = 2
# Each item is going to be a new dictionary, which we will
# eventually add the the list of payloads
new_payload = {}
# Now we can create a dict entry for key 'sku' in new_payload
new_payload['sku'] = Mbody[index:(index + SKU_size * 2)]
# We can't do this, because tag_size is undefined
#
# index = index + tag_size * 2
# We can't do this, because we have not yet added a 'tag' key
# to payload.
#
# print(payload[i]['tag'])
# Now append new_payload to payload
payload.append(new_payload)
i += 1

Related

Manipulate JSON values in Python

After making a post and receiving the return I want to treat him.
lambdaGetDependencies returns a JSON and I need specific values from the JSON, that's what I try to do inside the cycle.
if CLUSTER_ENDPOINT and CLUSTER_PORT:
data = lambdaGetDependencies(resource)
else:
print("provide CLUSTER_ENDPOINT and CLUSTER_PORT environment variables")
elements = data['result']['data']['#value']
dependencies = [None] * len(elements)
count = 0
j = 0
for i in elements:
while j < len(i['#value']):
x = {i['#value'][j]: i['#value'][j+1]['#value'][0]}
c.append(x)
dependencies[count] = i['#value'][j+1]['#value'][0]
count += 1
j += 1
return json.dumps(c)
The problem is that I get string indices must be integers on the line:
x = {i['#value'][j]: i['#value'][j+1]['#value'][0]}
and I don't get why. Any ideas?
i['#value'][j+1] is probably a string and not a dictionary. If that is the case then this i['#value'][j+1]['#value'][0] is invalid.

Iterating through JSON - typeError on list index

I'm getting a weird "casting" issue when trying to walk through a JSON object. As soon as the iteration value gets to 100, the script errors out and complains that the key values must be integer.
import json
#from pprint import pprint
with open('/tmp/myfile.json') as f:
data = json.load(f)
line_entries = len(data)
len_w = len(data[0]["w"])
#print(line_entries)
line_iter = 0
main_iter = 0
sub_iter = 0
while line_iter < line_entries:
v = data[line_iter]["v"]["h"]
c = data[line_iter]["v"]["d"]
print("=========================================================")
print("Dest: ", v)
print("Cart: ", c)
while sub_iter < len_wp:
sn = data[line_iter]["w"][sub_iter]["s"]["n"]
at = data[line_iter]["w"][sub_iter]["at"]
dt = data[line_iter]["w"][sub_iter]["dt"]
sub_iter = sub_iter + 1
print(sn)
print(at)
print(dt)
line_iter = line_iter + 1
print("=========================================================")
The script prints out fine for records 0 to 99, but from 100 it says:
v = data[line_iter]["v"]["h"]
TypeError: list indices must be integers or slices, not str
JSON objects may contain lists or dictionaries, among others. As long as you have a dictionary, you may access it via a string-type key like "v" in your example, but that does not work for lists. Thus my guess is that record 100 has the type of a list.

Python - change value of list item

My code is as follows with comments. it runs fine until it comes to changing the value of a list item i.e. data[x][y] = something.
Tdata = cursor.fetchall() #Get data from MYSQL database
data = list(Tdata) #Convert into list...not sure if absolutely required
APIData = APIDataList()
MPLlat = 0.0
MPLLon = 0.0
RadiusOI = 15
for i in (range(0,len(data))):
MPLCount = 0
MPLlat = data[i][2]
MPLLon = data[i][3]
MPLCount = CountofbikesnearMPL(MPLlat, MPLLon, RadiusOI)
if MPLCount>0:
data[i][4] = MPLCount #ERROR: here is where the error is kicking in.
#get error "tuple' object does not support
#item assignment"
I really cant figure out why this is happening and have tried googling but with no success. Any help will be deeply appreciated.
Thanks in advance.
C
cursor.fetchall() returns a list of tuples.
That means that data[i] will be a tuple, which is by definition immutable. If you want to modify data[i], you will need to turn your tuples into lists
data = [list(row) for row in Tdata]
or replace the entire row via tuple concatenation
data[i] = data[i][:4] + (MPLCount,) + data[i][5:]
Maybe it is cleaner to write it using enumerate:
for i, elem in enumerate(data):
# MPLCount = 0 - I suppose it is unnecessary since you overwrite the value below
MPLlat = elem[2]
MPLLon = elem[3]
MPLCount = CountofbikesnearMPL(MPLlat, MPLLon, RadiusOI)
if MPLCount > 0:
data[i] = elem[:4] + (MPLCount,) + elem[5:]
Is there a reason you name variables and functions ThisWay? If not, it would be nice if you follow PEP8 and name them this_way. Anyway be consistent and don't mix two styles together.

Making list of adjacent node pairs from Cube-formatted line file (using Python)

My files are formatted like this:
LINE NAME="FirstLine", MODE=15, ONEWAY=T, HEADWAY[1]=20, HEADWAY[2]=30,
HEADWAY[3]=20, HEADWAY[4]=30, HEADWAY[5]=30, VEHICLETYPE=2,
XYSPEED=20, N=-20609, -22042, -20600, 20601, 22839, 22838,
-20602, -20607, -20606, -20605, -20896, -20895, -20897, 20898,
-20899, -20905, -20906, -20910, 21104, -20911, -20912, 25065,
-21375
LINE NAME="SecondLine", MODE=15, ONEWAY=T, HEADWAY[1]=25, HEADWAY[2]=35,
[ETC]
I need to extract the lists of numbers that come after N= (one list for each N=), get rid of the minus-signs, and append each pair of adjacent numbers (e.g. [[20609, 22042], [22042, 20600]]) into a list of pairs. The major sticking part for Python-noob me is just extracting the lists of numbers as the first step (i.e. making what comes after each N= a list of its own).
If Python lists aren't ordered, I may have to make the lists strings and write each one as a line in a new file.
I was able to solve this by using the find method for LINE and N=. Finding LINE would increase an index and make a new item in a dictionary corresponding to that index. Finding N= would give the "definition" to that item in the dictionary -- a list with a single string element. Then for each item in the dictionary, I stripped spaces, replaced the - with '' (i.e. nothing), and used the split method with argument ',' to cut up the lists.
Then I zipped those lists Li[:-1] into themselves Li[1:] to get the adjacent-node pairs I needed.
Probably no one will ever find this useful (and I know it's probably convoluted), but here's my code:
with open(path + filename) as f:
i = 0
L = {}
for line in f:
existL = line.find("LINE")
existN = line.find("N=")
if existL > -1:
i = i + 1
L["Line" + str(i)] = []
if existN > -1:
go = 0
while go == 0:
txtNodes = line[line.rfind('=')+1:].strip()
nodes = txtNodes.split(',')
for node in nodes:
node = node.strip()
node = node.replace('-','')
if len(node) > 3:
L["Line" + str(i)].append(node)
try:
line = f.next()
if line.find("LINE") > -1:
go = go + 1
i = i + 1
L["Line" + str(i)] = []
except:
go = go + 1
Li = []
while i > 1:
L1 = L["Line" + str(i)][:-1]
L2 = L["Line" + str(i)][1:]
Lx = zip(L1,L2)
i = i-1
Li.extend(Lx)
I hate when people come to forums and don't follow up, so here's my follow-up. Sorry for posting in the wrong place initially.

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