web2py append dictionary to list - list

I create a list of dictionaries from excel. The code is listed below. What happens is the list contains the last row excel values for all the rows. I tried in python shell. It works fine. Why all the rows get updated with last row values?
d = {}
l = []
up = os.path.join(request.folder,'uploads')
workbook = xlrd.open_workbook(os.path.join(request.folder,'uploads','meas.xls'))
worksheet = workbook.sheet_by_name('Sheet1')
num_rows = worksheet.nrows - 1
num_cells = worksheet.ncols - 1
curr_row = -1
while curr_row < num_rows:
curr_row += 1
row = worksheet.row(curr_row)
#print 'Row:', curr_row
curr_cell = -1
while curr_cell < num_cells:
curr_cell += 1
# Cell Types: 0=Empty, 1=Text, 2=Number, 3=Date, 4=Boolean, 5=Error, 6=Blank
cell_type = worksheet.cell_type(curr_row, curr_cell)
cell_value = worksheet.cell_value(curr_row, curr_cell)
#print ' ', cell_type, ':', cell_value
if curr_cell == 0:
d['loc_of_work'] = cell_value
if curr_cell == 1:
d['n'] = cell_value
if curr_cell == 2:
d['t'] = cell_value
if curr_cell == 3:
d['l'] = cell_value
if curr_cell == 4:
d['b'] = cell_value
if curr_cell == 5:
d['d'] = cell_value
print 'dict'
print d.items()
l.append(d)
print 'len of list:'
print len(l)
print 'list:'
for i,j in enumerate(l):
print i,j

The issue is you are declaring d outside the while loop, which means within the loop you are simply overwriting the same dict with new values on every iteration. Your list simply contains multiple references to the same dict object, which contains the values from the last row because those are the last values to be written to the dict (all previous values are overwritten)
moveoing:
d = {}
inside the first while loop should fix your issue

Related

Q: Python3 - If Statements for changing list lengths

I am attempting to analyze data sets as lists of differing lengths. I am calling lines (rows) of my data set one by one to be analyzed by my function. I want the function to still be run properly regardless of the length of the list.
My Code:
f = open('DataSet.txt')
for line in iter(f):
remove_blanks = ['']
entries = line.split()
''.join([i for i in entries if i not in remove_blanks])
trash = (entries[0], entries[1])
time = int(entries[2])
column = [int(v) for v in entries[3:]]
def myFun():
print(entries)
print_string = ''
if column[0] == 100:
if column[1] >= 250 and column[2] == 300:
if len(column) >= 9:
digit = [chr(x) for x in column[4:9]]
print_string = ('code: ' + ''.join(str(digit[l]) for l in range(5)) + ' ')
if len(column) >= 13:
optional_digit = [chr(d) for d in column[9:13]]
for m in range(0, 4):
print_string += 'Optional Field: ' + optional_digit[m] + ''
else:
print_string += 'No Optional Field '
pass
pass
print(print_string)
print('')
myFun()
f.close()
What is happening is if the length of a line of my data is not long enough (i.e. the list ends at column[6]), I get the error:
line 17, in function
print('Code: ' + digit[l])
IndexError: list index out of range
I want it to still print Code: #number #number #number #number and leave any non-existent columns as blanks when it is printed so that one line may print as Code: ABC9 and the next print as Code: AB if there are differing list lengths.
Please help! :)
Well, just make sure you're not looping over a list longer than available:
print_string = 'code: ' + ''.join(str(digit[l]) for l in range(min(5, len(digit)))) + ' '
or better:
print_string = "code {} ".format("".join(str(dig) for dig in digit[:5]))
Although I have a feeling you're over-complicating this.

Dynamically use both python raw_input and raw_input().split()

The input format is:
6
1
2 5
2 7
2 9
1
1
Input:
First line contains an integer Q, the number of queries. Q lines follow.
A Type-1 ( Customer) Query, is indicated by a single integer 1 in the line.
A Type-2 ( Chef) Query, is indicated by two space separated integers 2 and C (cost of the package prepared) .
I want to read the input from stdin console and here is my code
n = int(input())
stack1 = []
for i in range(n):
x = input()
x = int(x)
if x == 2:
y = input()
stack1.append(y)
elif x == 1:
length = len(stack1)
if length > 0:
print(stack1.pop())
else:
print("No Food")
I have tried x,y = raw_input().split() this statement also fails because sometimes input has single value. Let us know how to read the defined input from stdin ???
Use len() to find length of string based on that change your stdin.
n = int(input())
for i in range(n):
s = input()
if(len(s) > 1):
x,y = s.split()
x = int(x)
else:
x = int(s)
print(x)
Cheers.

Why won't my csv list replace my blank values with "N"?

I'm attempting to create a function which reads a specific column of a csv file which currently alternates between empty values and "1", pops them into a list and then replaces them with an "N" for the empty value and "B" for the "1"'s. I'm pretty new to python, as well as programming in general, so any tips and all help is welcome. This is what I have so far, and it does process, but only replaces my "1"'s with "B"'s. I've double checked my csv and the position is definitely empty and does not contain spaces. I've also looked at other responses and tried to emulate some similar logic that appeared to be behind them, but something still doesn't seem to work. If someone could point me in the right direction it would be very much appreciated.
#sample data (for 195 entries):
["Header0,"Header1","Foundation","Header3"],
["abc1","a12n","","123"],
["def2","d13b","1","456"],
["ghi3","g12n","","789"],
def Foundation( csv_file_path, Remove_Header = False, Remove_SubHeader = False ):
delineator = ','
raw_file = file(csv_file_path, 'r')
return_List = []
n = 0
#Process lines in file
for line in raw_file.readlines():
#Check if to include or remove header
if (n == 0 ) and (Remove_Header == True):
n = n + 1
continue
#Check if to include or remove sub header
if (n == 1) and (Remove_SubHeader == True):
n = n + 1
continue
sList2 = line.replace("\n","").strip().split( delineator )
col_2 = str(sList2.pop(2))
for n in col_2:
if n == "1":
col_2 = col_2.replace("1", "B")
elif n == "":
col_2 = col_2.replace("", "N")
print col_2
return_List.append(sList2) #add my secondary list back to my main List? right?
sList2.insert(0, col_2)# insert back to my secondary list where it went
n = n + 1 #add to counter and move down the line
raw_file.close()
#Return the list
return return_List

loop doesn't iterate over all the csv file read, python2, pycharm

here is my code:
import csv
inp1 = raw_input('Enter your Hijjri year:')
intinp1 = int(inp1)
majmouaopen = open('Majmoua.csv')
majmouaread = csv.reader(majmouaopen)
majmouaread.next()
mabsoutaopen = open('Mabsouta.csv')
mabsoutaread = csv.reader(mabsoutaopen)
mabsoutaread.next()
hijrimiladimonthsopened = open('MiladiHijrimonths.csv')
hijrimiladimonthsread = csv.reader(hijrimiladimonthsopened)
yearslist = []
years = []
yearssection = []
monthssection = []
minutessection = []
def miladifromhijri(intinp1):#, inp2, intinp3):
fulyear = intinp1 - 1
n = 0
for row in majmouaread:
print row
introw = int(row[0])
if introw <= fulyear:
n += 1
years.append(introw)
continue
if n == len(years):
near = years[::-1][0]
nearlessyear = near
break
for row in majmouaread:
print row
my problem is with the last loop, it doesn't print all of the majmouaread files. for the first loop, which is the same, it does print all of the csv file rows.
What is causing the probblem, is it something in the code? or something happened to the csv file read? It looks fine with first loop?

Changing values in an list? [duplicate]

I want to remove some words from a list of words. I have a list with a recurring word and I want to get rid of it and I have no idea. I don't know whether I need to use a whole loop or regex.
from xlrd import open_workbook,error_text_from_code
book = open_workbook(inp)
sheet0 = book.sheet_by_index(0)
x = 0
y = 0
countr = sheet0.nrows
countc = sheet0.ncols
names = ''
variables = []
"different variables-----------------"
while x < countr -1:
x = x+1
y = y+1
cell = sheet0.cell(y,0)
names = names+ str(cell)
cell = sheet0.cell(y,1)
variables.append(cell)
country_text = names
countries = ', '.join(re.findall("('.*?')", country_text))
countries = countries.split()
print (variables)
print (countries)
What I get :
[number:150000.0, number:140000.0, number:300000.0]
and I need
[150000, 140000, 300000]
If you use a loop you can access to the value of a cell using this function:
sheet0.cell_value(curr_row, curr_cell)