Using index in Python to iterate through columns - python

I am trying to iterate through columns in a data file, to perform my task and then save the output to a file. I have almost 200 columns and unfortunately so far I can only get the required output by changing the column index manually (where ###). I have managed to get the index numbers that I want to use from my row names into a list (called x). I've been playing around with this but I am stuck as to how to make it iterate through these indices in the correct places. Below is what I have so far:
with open('matrix.txt', 'r') as file:
motif = file.readline().split()
x = [i for i, j in enumerate(motif)]
print x ### list of indices I want to use
for column in (raw.strip().split() for raw in file):
chr = column[0].split("_")
coordinates = "\t".join(chr)
name = motif[1] ### using column index
print name
for value in column[1]: ### using column index
if value == "1":
print coordinates
out = open("%s.bed" %name, "a")
out.write(str(coordinates)+"\n")
elif value == "0":
pass
When I return x I get:
x = [0, 1, 2, 3, 4,...]
Using motif[x[1]] returns the correct names and columns, however this is the same as me putting the index in manually. Any help is appreciated!

Instead of:
name = motif[1] ### using column index
print name
for value in column[1]: ### using column index
if value == "1":
print coordinates
out = open("%s.bed" %name, "a")
out.write(str(coordinates)+"\n")
elif value == "0":
pass
you can iterate through x since x is a list of the column indices:
for index in x:
name = motif[index]
print name
for value in column[index]:
if value == "1":
print coordinates
out = open("%s.bed" %name, "a")
out.write(str(coordinates)+"\n")
elif value == "0":
pass
You can read more about for loops here.

Related

I have a defined a variable inside a for loop, but when printing it outside of the loop it doesn't print correctly

Here is the code:
count_1 = 0
count_0 = 0
list = ('001111011011','000110001010','011010111111')`
for i in list:
index = 0
y = i[index]
if y == "1":
count_1 = count_1 + 1
if y == "0":
count_0 = count_0 + 1
if count_1 > count_0:
for i in list:
final_after_1 = []
if i[0] == "1":
final_after_1.append(i)
formatted = (','.join(final_after_1))
if count_0 > count_1:
for i in list:
final_after_1 = []
if i[0] == "0":
final_after_1.append(i)
formatted = (','.join(final_after_1))
if count_0 == count_1:
for i in list:
final_after_1 = []
if i[0] == "1":
final_after_1.append(i)
print(final_after_1)
formatted = (','.join(final_after_1))
print(formatted)
(Apologies in advance if this question is worded badly, this is my first time asking a question).
This piece of code is working fine except for this one issue. It is designed to identify the first index of each 12-digit number in the list, and then work out if a 1 or 0 is more common in this position. It then selects all the numbers with the more common number in the first position and adds them to a list. I want to print this list at the end of the program.
I have defined a variable (called formatted) to be equal to a list of various numbers. When I print it out within the loop I have defined it in, it prints all the numbers that should be in the list, like this:
When I print it outside of the loop as in the code above it returns only the final number:
011010111111
Whereas printing it inside the loop like this:
if count_0 > count_1:
for i in list:
final_after_1 = []
if i[0] == "0":
final_after_1.append(i)
formatted = (','.join(final_after_1))
print(formatted)
does return this full desired list:
001111011011
000110001010
011010111111
Any ideas why this is happening?
Within you loop(s) the value of formatted is updated for each iteration. After the last iteration it is no longer updated and that last value is the output of the last print statement.
A simpler example:
for x in range(100):
pass//looping over, x is 0..99
print(x)
This will print out 99, the last value held by the variable "x".
Problably your code is updateing the variable for each iteration so in a for loop you need to append the values and not overwrite them, for example:
a = 0
b = 0
for i in 10:
a = 1
b = b + 1 # using the last value
print(a) # 1
print(b) # 9
First of all you shouldn't use "list" as a variable name because is a built-in name to instanciate lists or arrays. In second your code is repeated 3 times just for count a bit, let me show a better way with list compreenssions:
l = ('001111011011','000110001010','011010111111')
first_elements = list()
for x in l:
v = x[0] # first element
first_elements.append(int(v))
# [0,0,0]
count_0 = first_elements.count(0)
# count_0 = 3
count_1 = first_elements.count(1)
# count_1 = 0
Using list compreenssion
first_elements = [int(x[0]) for x in l]
# [0,0,0]
References: list compreenssions, list, list.count

List index out of range when trying to read in a txt file in Python

I want to read a txt file in Python. The text file consists of 3 columns, all are separated by a ','. One column represents the ID, one for a random float number, and one for the assigned attribute (solo, not solo, acc).
My goal is to convert values for 'solo' and 'acc' to 'not solo', and afterwards calculate the variable y.
The user is asked to enter an ID (number) in. Then I want to convert the lines of the txt file into a list and search for the remaining values, e.g. User enters in: 45 --> I want to search for the assigned value, then convert it to 'not solo' and calculate y. In the end, I want to print the assigned value in the unit 'not solo' as well as the y-calculation.
However, when I am trying to find the values, I get an error saying that my list index would be out of range. Does anyone have a clue how to fix this?
I am browsing for hours but I can't find a solution that works.
Thank you so much!
import math
fobj = open('test.txt', 'r')
file_content = fobj.readline()
fobj.close()
for file in file_content:
file = file.strip()
file_list = file.split(',')
ID_q = int(input("Please enter number [else enter 'finished']:"))
ID = ID_q + 1
if ID_q != "finished":
output = "Your ID {} is assigned to following values: ".format(ID_q)
print(output)
#Now the fun part starts!
chosen_line = [ID]
for position, line in enumerate(file_content):
if position in chosen_line:
file_line = chosen_line.split(',')
ID_inline = file_list[0]
print(ID_inline)
if file_list[2] == 'solo':
x = float((float(file_list[1])) * (math.pi/180))
x_result = float("not solo: {0}".format(x))
x_result = round(x_result, 2)
y = float(math.sin((6*(float(file_list[1])))-(3*math.cos((float(file_list[1]))))))
function = float("f(x) = {0}".format(y))
function = round(function, 2)
print(x_result)
print(function)
elif file_list[2] == 'acc':
x = float((float(file_list[1])) * (math.pi/200))
x_result = float("not solo: {0}".format(x))
x_result = round(x_result, 2)
y = float(math.sin((6*(float(file_list[1])))-(3*math.cos(float(file_list[1])))))
function = float("f(x) = {0}".format(y))
function = round(function, 2)
print(x_result)
print(function)
else:
x = ID
y = float(math.sin((6*(float(file_list[1])))-(3*math.cos(float(file_list[1])))))
function = float("f(x) = ".format(y))
function = round(function, 2)
print(x)
print(function)
else:
print("Bye.")
When you do this:
fobj = open('test.txt', 'r')
file_content = fobj.readline()
fobj.close()
You are reading only one line, not the whole file.

How to change values in nested list python

The matrix represents cell points. If we imagine these cell points being a grid, we need to make the values within the matrix equal to the input T1 in quadrants 2 and 4 and the values input T2 for quadrants 1 and 3. As in, from row 0 to 2 and column 0 to 3 it should be the value T1. Also, I need to make this appear as cells, with lines in between all rows/columns.
#input values needed
A = input("Enter a value for the first heater/cooler temp: ")
B = input("Enter a value for the second heater/cooler temp: ")
T1 = input("Enter a value for the first initial plate temp: ")
T2 = input("Enter a value for the second initial plate temp: ")
#the stabilizing criterion value
matrix = []
for row in range(0,6):
matrix.append([])
for column in range(0,9):
matrix[row].append(column)
for row in matrix:
print(row)
In this code, row in range(0,6) refers to all positions of the matrix that are in the first row, then second, and so on. It loops over all the rows.
So matrix[0][x] refers to all the positions in the 0th row (and you can access each position by setting x = 1, 2, ...).
What you want to do, is set values to T1 for a specific set of rows and columns, right?
Since you are anyway looping through all the rows and columns, you can check if at any point, the combination of row and column falls in the desired range:
if row < 3 and column < 4:
matrix[row][column] = T1
What this does is, whenever the combination of row and column numbers falls in the range that is, row = 0 to 2 and column = 0 to 3, it sets the value at those positions in the matrix, to T1.
Does this answer your question?
Now about the printing part, you can try a function like this:
def printy(P):
for i in range(len(P[0])):
print '---',
print
for i in range(len(P)):
for j in range(len(P[0])):
print P[i][j], '|',
print
for i in range(len(P[0])):
print '---',
print

Converting string to float

I am trying to write a program that tallies the values in a file. For example, I am given a file with numbers like this
2222 (First line)
4444 (Second line)
1111 (Third line)
My program takes in the name of an input file (E.G. File.txt), and the column of numbers to tally. So for example, if my file.txt contains the number above and i need the sum of column 2, my function should be able to print out 7(2+4+1)
t1 = open(argv[1], "r")
number = argv[2]
k = 0
while True:
n = int(number)
t = t1.readline()
z = list(t)
if t == "":
break
k += float(z[n])
t1.close()
print k
This code works for the first column when I set it to 0, but it doesn't return a consistent result when I set it to 1 even though they should be the same answer.
Any thoughts?
A somewhat uglier implementation that demonstrates the cool-factor of zip:
def sum_col(filename, colnum):
with open(filename) as inf:
columns = zip(*[line.strip() for line in inf])
return sum([int(num) for num in list(columns)[colnum]])
zip(*iterable) flips from row-wise to columnwise, so:
iterable = ['aaa','bbb','ccc','ddd']
zip(*iterable) == ['abcd','abcd','abcd'] # kind of...
zip objects aren't subscriptable, so we need to cast as list before we subscript it (doing [colnum]). Alternatively we could do:
...
for _ in range(colnum-1):
next(columns) # skip the columns we don't need
return sum([int(num) for num in next(columns)])
Or just calculate all the sums and grab the sum that we need
...
col_sums = [sum(int(num) for num in column) for column in columns]
return col_sums[colnum]

Select from list by index, but keep other associated items in list

If I have a 2dlist of points like this...
myList=[['ab','0_3','-1','1'],['bm','2_1','-3','2'],['am','4_1','-1','3'],...]]
where '-1','1' for example are x, y coordinates (the last 2 columns) and I want display just part of the list with its index like this...
[0] ab # I don't want to display the other list items, just the index and first col
[1] bm
[2] am
...so the user can select one of them by index number to make a point of origin. I figured I could enumerate as such...
for row in enumerate(myList):
i, a= row
col= (i, a[0])
newList.append(col)
print cols
But once I ask the user to select one ie. user selects '0' and that sets the variable origin='ab', how can I get the x,y (or [2],[3]) columns associated with origin to use as the origin coordinates (I need to be able to compare to the rest of the list)?
Using this method, can I somehow use the variable assigned to the selected point ie. origin = ab, and then get it's x,y and assign them to x1, y1...
Because enumerate gives the 2 tuples (i, a) and appends them to newList, is that all I have in newList, or can I also append the other columns but not display them?
I hope my explanation is clear enough... I only have badly butchered code atm
So I finally got most of this working with...
import csv
myList=[]
try:
csvr = open('testfile.csv','r')
next(csvr, None)
theList = csv.reader(csvr)
for row in theList:
myList.append(row)
for row in enumerate(myList):
i, a = row
print i, a[0]
except IOError:
print 'Error!!!'
try:
choice = raw_input("Select a set: ") # Can also enter 'e'
if choice=='e'
print 'exiting'
else:
pass
user_choice = myList[int(choice)]
name, id, x, y= user_choice
print name, id,
return float(x), float(y)
except:
print 'error'
It prints as expected and I can return x, y now which is great but it just keeps prompting me to enter a number. Any suggestions?
1) Keeping the list format, you can use the user's choice as a list index:
myList = [['ab','0_3','-1','1'],['bm','2_1','-3','2'],['am','4_1','-1','3']]
for row in enumerate(myList):
i, a = row
print i, a[0]
choice = int(raw_input("Select a set: "))
user_choice = myList[choice]
name, id, x, y = user_choice
print name, id, float(x) + float(y) # use float() to convert strings to floats
Sample output:
~ $ python tester.py
0 ab
1 bm
2 am
Select a set: 1
bm 2_1 -1.0

Categories

Resources