I have a .txt file and I would like to print lines 3, 7, 11, 15,...
So, after printing the third line, I would like to print every 4th line afterward.
I began by looking at the modulus operator:
#Open the file
with open('file.txt') as file:
#Iterate through lines
for i, line in enumerate(file):
#Choose every third line in a file
if i % 3 == 0:
print(line)
#Close the file when you're done
file.close()
but that approach prints every third line. If i % 3 == 1 that prints lines 1, 4, 7, 10, 13 etc.
Instead of using modulo, simply just use addition, start it with the first line you want to show, and then add 4 to it
next_line = 2 # Line 3 is index 2
for i, line in enumerate(file):
if i == next_line:
print(line)
next_line = next_line + 4
Your code is almost fine, except for the modulo: you want the remainder of the division by 4 to be 3.
with open('file.txt') as file:
for i, line in enumerate(file):
if i % 4 == 3:
print(line)
Note that you don't need to explicitely close your file at the end: that's what with is intended for, it makes sure that your file gets closed whatever happens.
So you want to something to happen every fourth time, that means modulo 4. Try changing your if to if i % 4 == N: with a good number for N.
By the way, when using the with statement you have don't have to call close(), it does so automatically.
How about:
# Fetch all lines from the file
lines = open('20 - Modular OS - lang_en_vs2.srt').readlines()
# Print the 3rd line
print(lines[2])
# throw away the first 3 lines, so the modulo (below) works ok
for i in range(3):
del(lines[0])
# print every 4th line after that
for (i in range(len(lines)):
if (i > 0 and i % 4 == 0):
print(lines[i])
Read every line into an array.
Output the 3rd line.
We then need every fourth line, so by deleteing the first 3 elements, it's easy to simply test against modulo 4 (the "% 4") and output the line.
x = 0
with open('file.txt') as file:
#Iterate through lines
for i, line in enumerate(file):
x += 1
#Choose every third line in a file
if x == 4:
print(line)
x = 0
#Close the file when you're done
file.close()
Result
>>> i = 0
>>> for x in range(0, 100):
... i += 1
... if i is 4:
... print(x)
... i = 0
3
7
11
15
19
23
27
31
35
39
43
47
51
55
59
63
67
71
75
79
83
87
91
95
99
file = open('file.txt')
print(file[2])
#Iterate through lines
for i in file:
#Choose every third line in a file, beginning with 4
if i % 4 == 0:
print(i+3)
elif i % 4 == 0:
print(i)
This works, but isn't super elegant.
Related
I am writing a code for extracting specific lines from my file and then look for the maximum number, more specifically for its position (index).
So I start my code looking for the lines:
with open (filename,'r') as f:
lines = f.readlines()
for index, line in enumerate(lines):
if 'a ' in line:
x=(lines[index])
print(x)
So here from my code I got the lines I was looking for:
a 3 4 5
a 6 3 2
Then the rest of my code is looking for the maximum between the numbers and prints the index:
y = [float(item) for item in x.split()]
z=y.index(max(y[1:3]))
print(z)
now the code finds the index of the two largest numbers (so for 5 in the first line and 6 in the second):
3
1
But I want my code compare also the numbers between the two lines (so largest number between 3,4, 5,6,3,2), to have as output the index of the line, where is in the file the line containing the largest number (for example line 300) and the position in line (1).
Can you suggest to me some possible solutions?
You can try something like that.
max_value - list, where you can get max number, line and position
max_value = [0, 0, 0] # value, line, position
with open(filename, 'r') as f:
lines = f.readlines()
for index, line in enumerate(lines):
if 'a ' in line:
# get line data with digits
line_data = line.split(' ')[1:]
# check if element digit and bigger then max value - save it
for el_index, element in enumerate(line_data):
if element.isdigit() and int(element) > max_value[0]:
max_value = [int(element), index, el_index]
print(max_value)
Input data
a 3 4 5
a 6 3 2
Output data
# 6 - is max, 1 - line, 0 - position
[6, 1, 0]
You should iterate over every single line and keep track of the line number as well as the position of the items in that line all together. Btw you should run this with python 3.9+ (because of .startswith() method.)
with open(filename) as f:
lines = [line.rstrip() for line in f]
max_ = 0
line_and_position = (0, 0)
for i, line in enumerate(lines):
if line.startswith('a '):
# building list of integers for finding the maximum
list_ = [int(i) for i in line.split()[1:]]
for item in list_:
if item > max_:
max_ = item
# setting the line number and position in that line
line_and_position = i, line.find(str(item))
print(f'maximum number {max_} is in line {line_and_position[0] + 1} at index {line_and_position[1]}')
Input :
a 3 4 5
a 6 3 2
a 1 31 4
b 2 3 2
a 7 1 8
Output:
maximum number 31 is in line 3 at index 4
You can do it like below. I commented each line for explanation. This method differs from the others in that: using regex we are getting the current number and it's character position from one source. In other words, there is no going back into the line to find data after-the-fact. Everything we need comes on every iteration of the loop. Also, all the lines are filtered as they are received. Between the 2, having a stack of conditions is eliminated. We end up with 2 loops that get directly to the point and one condition to see if the requested data needs to be updated.
import re
with open(filename, 'r') as f:
#prime data
data = (0, 0, 0)
#store every line that starts with 'a' or blank line if it doesn't
for L, ln in enumerate([ln if ln[0] is 'a' else '' for ln in f.readlines()]):
#get number and line properties
for res in [(int(m.group('n')), L, m.span()[0]) for m in re.compile(r'(?P<n>\d+)').finditer(ln)]:
#compare new number with current max
if res[0] > data[0]:
#store new properties if greater
data = res
#print final
print('Max: {}, Line: {}, Position: {}'.format(*data))
I need to write a Python program to read the values in a file, one per line, such as file: test.txt
1
2
3
4
5
6
7
8
9
10
Denoting these as j1, j2, j3, ... jn,
I need to sum the differences of consecutive values:
a=(j2-j1)+(j3-j2)+...+(jn-j[n-1])
I have example source code
a=0
for(j=2;j<=n;j++){
a=a+(j-(j-1))
}
print a
and the output is
9
If I understand correctly, the following equation;
a = (j2-j1) + (j3-j2) + ... + (jn-(jn-1))
As you iterate over the file, it will subtract the value in the previous line from the value in the current line and then add all those differences.
a = 0
with open("test.txt", "r") as f:
previous = next(f).strip()
for line in f:
line = line.strip()
if not line: continue
a = a + (int(line) - int(previous))
previous = line
print(a)
Solution (Python 3)
res = 0
with open("test.txt","r") as fp:
lines = list(map(int,fp.readlines()))
for i in range(1,len(lines)):
res += lines[i]-lines[i-1]
print(res)
Output: 9
test.text contains:
1
2
3
4
5
6
7
8
9
10
I'm not even sure if I understand the question, but here's my best attempt at solving what I think is your problem:
To read values from a file, use "with open()" in read mode ('r'):
with open('test.txt', 'r') as f:
-your code here-
"as f" means that "f" will now represent your file if you use it anywhere in that block
So, to read all the lines and store them into a list, do this:
all_lines = f.readlines()
You can now do whatever you want with the data.
If you look at the function you're trying to solve, a=(j2-j1)+(j3-j2)+...+(jn-(jn-1)), you'll notice that many of the values cancel out, e.g. (j2-j1)+(j3-j2) = j3-j1. Thus, the entire function boils down to jn-j1, so all you need is the first and last number.
Edit: That being said, please try and search this forum first before asking any questions. As someone who's been in your shoes before, I decided to help you out, but you should learn to reference other people's questions that are identical to your own.
The correct answer is 9 :
with open("data.txt") as f:
# set prev to first number in the file
prev = int(next(f))
sm = 0
# iterate over the remaining numbers
for j in f:
j = int(j)
sm += j - prev
# update prev
prev = j
print(sm)
Or using itertools.tee and zip:
from itertools import tee
with open("data.txt") as f:
a,b = tee(f)
next(b)
print(sum(int(j) - int(i) for i,j in zip(a, b)))
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am new at this and couldn't search my exact problem. Though it may be simple to many of you, it is certainly a bowl full of aggravation to me. So, here it is...
I have a text file with columns and rows. The columns are string and the rows are numeric.
EXAMPLE: text file.
Line 1: a.1 2.g 2.2 b.3
Line 2: --------------------
Line 3: 1 2 4 1
Line 4: 3 3 1 1
Line 5: 2 1 5 8
I need to read the text file and do some simple math.
1. sum rows 3,4,5.
The final result should like the following:
FINAL
Line 1:
Line 2:
Line 3: 8
Line 4: 8
Line 5: 16
Here is what i have so far...
files = open("exam-grades.txt", "r")
line_number = 1
for line in files:
if (line_number == 1 or line_number == 2):
continue
else:
sum = 0
numbers = line.split("\t")
for n in numbers:
sum = sum + float(n)
print "Line #: %d / Sum is %d ."%(line_number,sum)
line_number = line_number + 1
line_number is 1 initially, so it hits the first if statement and continues without incrementing line_number, and thus does the same thing for every line, and doesn't process any of them.
You could correct for this by replacing the top of your loop like so:
for line in files:
if line_number>=3:
sum = 0
...
with open("exam-grades.txt", "r") as f:
for i, line in enumerate(f, start=1):
if i >= 3:
l = line.split()
print l[0], l[1], sum((int(i) for i in l[2:] if i.isdigit()))
Logic here is pretty simple, you're enumerating lines in a files starting from 1.
Checking if a line number is 3 or greater, splitting a line into a list and verifying if a list element might be converted to int, if it might we summing it up and print out.
I would try to make it bit more flexible - i.e. we won't sum up numbers for lines where at least one value can't be converted to float/number:
def to_number(s):
try:
return float(s)
except ValueError:
return None
def sum_in_line(s):
sm = 0
cols = s.split()
try:
return sum(to_number(x) for x in cols)
except TypeError:
return ''
with open("exam-grades.txt", "r") as f:
i = 1
for line in f:
print('%4d:\t%s' % (i, sum_in_line(line)))
i += 1
Input data:
a.1 2.g 2.2 b.3
--------------------
1 2 4 1
3 3 1 1
2 1 5 8
1 a Z 12
Output:
1:
2:
3: 8.0
4: 8.0
5: 16.0
6:
1) Use pass instead of continue, if you use continue line_number will not be updated
2) to get numbers use first_part, numbers = line.split(':');numbers = number.split().
because if you try to get numbers like you did it will fail:
>>> sum = 0
>>> line="Line 3: 1 2 4 1"
>>> numbers = line.split("\t")
>>> numbers
['Line 3:', '1', '2', '4', '1']
>>> for n in numbers:
... sum = sum + float(n)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError: could not convert string to float: Line 3:
You shoud skip the first element 'Line 3:'.
Try this:
files = open("exam-grades.txt", "r")
line_number = 1
for line in files:
if (line_number == 1 or line_number == 2 or line_number == 3):
print "Line %d:" % line_number
pass
else:
sum = 0
first_part, numbers = line.split(":")
for n in numbers.split():
sum = sum + float(n)
print "Line %d: Sum is %d" % (line_number,sum)
line_number = line_number + 1
Seems a bit like a natural for regular expressions to me, depending on the complexity of your numbers... in this example, I have "data" as a generic iterator for your input data:
import re
valid = re.compile(r'^(?:\s*(\d+\s*))+\s*$')
numbers = re.compile(r'(\d+)')
for line,row in enumerate(data):
if valid.match(row):
print "Line #: %d / Sum is %d ."%(line+1,sum(map(int, numbers.findall(row))))
Okay so my question involves using PYTHON language please - Nothing else.
Basically, I have a file with a layout such as below:
X
Y
Z
A
B
C
1
2
3
And I would look at that and say X, A and 1 mark a new step! (because their indent is larger than the previous line basically). So I want to put in a new line with text Step 1, Step 2 etc, for each new step.
Note: I care more about how to put the new line in at the correct place, than how to increase the value of N with each Step.
Note 2: The file will vary in row count, so I cannot simply use at line 3, 6, 9 etc.. That's useless to me unfortunately.
You may want a code something like -
start = 1
lines = ['Step' + str(start) + ':\n']
with open('file.txt','r') as inF:
prevspace = -1
for line in inF:
lspaces = len(line) - len(line.lstrip())
if lspaces > prevspace and prevspace != -1:
lines.append('Step' + str(start+1) + ':\n')
start = start + 1
lines.append(line)
prevspace = lspaces
else:
lines.append(line)
prevspace = lspaces
ifF.close()
with open('newfile.txt','w') as outF:
for line in lines:
outF.write(line)
outF.flush()
outF.close()
I know that Python can read numbers like:
8
5
4
2
2
6
But I am not sure how to make it read it like:
8 5 4 2 2 6
Also, is there a way to make python read both ways? For example:
8 5 4
2
6
I think reading with new lines would be:
info = open("info.txt", "r")
lines = info.readlines()
info.close()
How can I change the code so it would read downwards and to the sides like in my third example above?
I have a program like this:
info = open("1.txt", "r")
lines = info.readlines()
numbers = []
for l in lines:
num = int(l)
numbers.append(str(num**2))
info.close()
info = open("1.txt", "w")
for num in numbers:
info.write(num + "\n")
info.close()
How can I make the program read each number separately in new lines and in just lines?
Keeping them as strings:
with open("info.txt") as fobj:
numbers = fobj.read().split()
Or, converting them to integers:
with open("info.txt") as fobj:
numbers = [int(entry) for entry in fobj.read().split()]
This works with one number and several numbers per line.
This file content:
1
2
3 4 5
6
7
8 9 10
11
will result in this output for numbers:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
This approach reads the whole file at once. Unless your file is really large this is fine.
info = open("1.txt", "r")
lines = info.readlines()
numbers = []
for line in lines:
for num_str in line.split(' '):
num = int(num_str)
numbers.append(str(num**2))
info.close()
info = open("test.txt", "r")
lines = info.readlines()
numbers = []
for l in lines:
l = l.strip()
lSplit = l.split(' ')
if len(lSplit) == 1:
num = int(l)
numbers.append(str(num**2))
else:
for num in lSplit:
num2 = int(num)
numbers.append(str(num2**2))
print numbers
info.close()
A good way to do this is with a generator that iterates over the lines, and, for each line, yields each of the numbers on it. This works fine if there is only one number on the line (or none), too.
def numberfile(filename):
with open(filename) as input:
for line in input:
for number in line.split():
yield int(number)
Then you can just write, for example:
for n in numberfile("info.txt"):
print(n)
If you don't care how many numbers per line, then you could try this to create the list of the squares of all the numbers.
I have simplified your code a bit by simply iterating over the open file using a with statement, but iterating over the readlines() result will work just as well (for small files - for large ones, this method doesn't require you to hold the whole content of the file in memory).
numbers = []
with open("1.txt", 'r') as f:
for line in f:
nums = line.split()
for n in nums:
numbers.append(str(int(n)**2))
Just another not yet posted way...
numbers = []
with open('info.txt') as f:
for line in f:
numbers.extend(map(int, line.split()))
file_ = """
1 2 3 4 5 6 7 8
9 10
11
12 13 14
"""
for number in file_ .split():
print number
>>
1
2
3
4
5
6
7
8
9
10
11
12
13
14