opening txt file and creating lists from the txt file - python

file = open('covid.txt', 'rt')
everything = file.read()
list = file.read()
i = [row.rstrip('\n') for row in everything]
print(i)
covid = []
counter = 0
for number in line.split(" "):
file.append(number)
for x in range(4):
print(x)
file.close()
I'm trying to Read the file "covid.txt" into two lists. The first list should contain all the "day" values from the file. The second list should contain all the "new cases" values.
my list in column
0 188714
1 285878
2 1044839
3 812112
4 662511
5 834945
6 869684
7 397661
8 484949
I needed to be this way
x = [ 0, 1 , 2, 3,...]
y = [188714, 285878, 1044839, 812112, ...]
I have tried so many different things I'm new to Python and trying to figure out how to start this. anyone can lead me to the right direction ?

Assuming your data file has all of those numbers in one long line, this should work:
# Read the words from the file. This is a list, one word per entry.
words = open('covid.txt','rt').read().split()
# Convert them to integers.
words = [int(i) for i in words]
# Divide into two lists by taking every other number.
x = words[0::2]
y = words[1::2]
print(x)
print(y)
Followup
Given this data:
0 188714
1 285878
2 1044839
3 812112
4 662511
5 834945
6 869684
7 397661
8 48494
My code produces this result:
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[188714, 285878, 1044839, 812112, 662511, 834945, 869684, 397661, 48494]
which is exactly what you said you wanted.

with open('covid.txt','rt') as f:
all_lines = [line.split(' ') for line in f]
x, y = zip(*all_lines)
x and y will be tuples though. You can cast by list(x)

Related

list comprehension always returns empty list

making a function that recieves numbers separated by spaces and adds the first element to the rest, the ouput should be a list of numbers if the first element is a number
i'm trying to remove all non numeric elements of list b
examples- input: 1 2 3 4
output: [3, 4, 5] (2+1, 3+1, 4+1)
input: 1 2 b 4
output: [3, 5] (2+1,b is purged, 4+1)
input: a 1 2 3
output: Sucessor invalido
linha = input()
a = linha.split()
b = [x for x in (a[1:]) if type(x)==int]
b = [eval(x) for x in b]
c = eval(a[0])
d = []
d.append(c)
f = d*len(b)
def soma():
if type(c)!= int: return print("Sucessor invalido")
else: return list(map(lambda x, y: x + y, b, f))
g = soma()
g
> this condition always returns an empty list
if type(x)==int
sorry if im not clear, i started learning recently
Two things:
The results of input are always strings. When you split the string, you end up with more strings. So even if that string is '7', it is the string 7, not the integer 7.
If you want to check if an object is of a type, use isinstance(x,int) rather than type(x)==int.
To accomplish what it looks like you are doing, I dunno if you can get it with list comprehension, since you probably want a try:...except:... block, like this.
linha = input()
a = linha.split()
b = [] #empty list
for x in a[1:]: # confusing thing you are doing here, also... you want to skip the first element?
try:
x_int = int(x)
b.append(x_int)
except ValueError:
pass
...
You need to convert the numbers separated by lines to integers, after checking that they are valid numberic values like this:
b = [int(x) for x in (a[1:]) if x.isnumeric()]
this is because your input will be a string by default, and split() will be just a list of strings
Your input is string, you need to cast it to int and then do calculation to append it to a new list.
The function should check for the index 0 first using str.islpha() method. If it's an alphabet, return invalid input.
Use try except when iterating the input list. If some element can't be cast to int it will continue to the next index.
def soma(linha):
if linha[0].isalpha():
return f"Sucessor invalido"
result = []
for i in range(len(linha) - 1):
try:
result.append(int(linha[0]) + int(linha[i+1]))
except ValueError:
continue
return result
linha = input().split()
print(soma(linha))
Output:
1 2 3 4
[3, 4, 5]
1 2 b 4
[3, 5]
a 1 2 3
Sucessor invalido

Extract the index of largest number in different lines

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))

Dijkstra python library passing value to the add_edge in Graph

I am trying to use the in-build Dijkstar library from Python and have query on passing add_edge values. Please help.
from dijkstar import find_path, Graph
graph = Graph()
input_file = input('Input the file name')
w = list()
i = 0
with open(input_file, 'r') as file:
for line in file:
for word in line.split():
w.append(word)
graph.add_edge(w[0], w[1], w[2])
print(w[0], w[1], w[2])
i = 0
w.clear()
print(find_path(graph, 1, 4))
The input file is following and it's working fine for w[0], w[1] and w[2]
1 2 1000
2 3 2000
3 4 3000
1 4 4000
The output is showing error as follows:
raise NoPathError('Could not find a path from {0} to {1}'.format(s, d))
dijkstar.algorithm.NoPathError: Could not find a path from 1 to 4
There is a path from 1 to 4 in two ways, then why it shows the error, not able to understand.
It would be great if any help I can get.
Believe issue was you where not converting input to numbers (i.e. weights were still strings).
Try the following.
Code
from dijkstar import find_path, Graph
input_file = input('Input the file name: ')
with open(input_file, 'r') as file:
graph = Graph() # place closer to where first used
for line in file:
line = line.rstrip() # remove trailing '\n'
w = list(map(int, line.split())) # convert line to list of ints
graph.add_edge(w[0], w[1], w[2]) # add edge with weights
print(w[0], w[1], w[2])
print(find_path(graph, 1, 4))
Input
file.txt
1 2 1000
2 3 2000
3 4 3000
1 4 4000
Output
PathInfo(nodes=[1, 4], edges=[4000], costs=[4000], total
_cost=4000)
Comments
No need to declare w as a list or to clear it between usage
w = list() # no need
w.clear() # no need
You should almost always strip off the trailing '\n' when iterating over a file
line = line.rstrip()
This is an inefficient way of placing elements in w
for word in line.split():
w.append(word)
Simpler just to assign directly.
w = line.split()
However, w would be filled with strings, so need to map to ints.
w = list(map(int, line.split()))
Variable i is not used (or needed) so remove.
i = 0

Sum of everything inside a list [duplicate]

This question already has answers here:
Sum of strings extracted from text file using regex
(10 answers)
Closed 6 years ago.
I am extracting numbers from sentences within a large file. Example sentence (in file finalsum.txt):
the cat in the 42 hat and the cow 1772 jumps over the moon.
I then use regular expressions to create a list where I want to add together 1772 + 42 for the entire file creating a final sum of all the numbers.
Here is my current code :
import re
import string
fname = raw_input('Enter file name: ')
try:
if len(fname) < 1: fname = "finalsum.txt"
handle = open(fname, 'r')
except:
print 'Cannot open file:', fname
counts = dict()
numlist = list()
for line in handle:
line = line.rstrip()
x = re.findall('([0-9]+)', line)
if len(x) > 0:
result = map(int, x)
numlist.append(result)
print numlist
I know this code can be written in two lines using line comprehension, but I am just learning. Thank you!
You should not append the list but instead join the lists using + operator.
for line in handle:
line = line.rstrip()
x = re.findall('([0-9]+)', line)
if len(x) > 0:
result = map(int, x)
numlist+=result
#numlist.append(result)
print numlist
print sum(numlist)
Illustration:
>>> a = [1,2]
>>> b = [2,3]
>>> c = [4,5]
>>> a.append(b)
>>> a
[1, 2, [2, 3]]
>>> print b + c
[2, 3, 4, 5]
As you can see, append() appends list object at the end where as + joins the two lists.
Check this:
import re
line = 'the cat in the 42 hat and the cow 1772 jumps over the moon 11 11 11'
y = re.findall('([0-9]+)', line)
print sum([int(z) for z in y])
It does not create nested lists rather it adds all the value in a given list after converting it to integer. You can manage a temporary variable which will store the final sum and keep adding the sum of all the integers in the current line to this temporary variable.
Like this:
answer = 0
for line in handle:
line = line.rstrip()
x = re.findall('([0-9]+)', line)
if len(x) > 0:
answer += sum([int(z) for z in x])
print answer

How to make Python read new lines and just lines?

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

Categories