Create a list from file in python - python

I have a .txt file like this:
John 26
Mary 48
Nick 34
I want import them and put them in a list so that I can find specific elements. For example age[1] would have the value 48, name[1] the value Mary etc.
I tried doing
import sys,random
f = open('example.txt', 'r')
for line in f:
tokens=line.split()
a=tokens[0]
print a[1]
but the result of print a[1] is the second letter of each string.

Instead of a[1], you want tokens[1].
This is the value of a, which is the first element of tokens:
Nick
But the second element of tokens is the age:
"34"
As #user mentioned, you probably wanted to have it as integer, not a string. You can convert it to integer:
a = int(tokens[1])
#thefourtheye proposed a nice solution. I think i'll propose to store it in a dictionary:
with open('example.txt') as f:
ages = {}
for line in f:
d = line.split()
ages[d[0]] = int(d[1])
And here is ages:
{'John':26, 'Mary':48, 'Nick':34}
To retrieve the age of John:
print(ages['John'])
Hope this helps!

While reading from a file, always use with, so that you dont have to worry about closing the file.
Then, you can read lines and split them and finally unzip them like this
with open('Input.txt', 'r') as inFile:
names, ages = zip(*(line.rstrip().split() for line in inFile))
print names, ages
Output
('John', 'Mary', 'Nick') ('26', '48', '34')
You can access the individual names and ages like this
names[0], ages[0]

Related

Nested list missing after read from file

So, i have a nested list written into a file.txt
students = []
info = []
name = input("Name: ")
age = input("Age: ")
info.append(name)
info.append(age)
students.append(info)
my_file = open("file.txt", "a")
for data in students:
my_file.write("%s\n" % data)
my_file.close()
The contents in the file are in this format:
['john', '19']
['nick', '20']
Afterwards, i'm using nested loop to access the content of file.txt
my_file = open("file.txt", "r")
search_keyword = input("Please Enter Student Name: ")
for students in my_file:
for info in students:
print(info)
Expected output:
john
19
nick
20
Actual output:
j
o
h
n
1
9
n
i
c
k
2
0
Can someone explain why the inner list is missing after extracting from a file, as the loop treats each individual alphabet as an element.
Uh, I'm not 100% sure but maybe try: my_file.writelines("")
This seems a good candidate for pickle since you have a Python data structure you want to preserve.
import pickle
lol = [['john', '19'],['nick', '20']]
with open('lol.pickle','wb') as f:
pickle.dump(lol,f)
del lol
print(lol)
# NameError: name 'lol' is not defined
with open('lol.pickle','rb') as f:
lol = pickle.load(f)
print(lol)
# [['john', '19'], ['nick', '20']]
You have read the data as a string, so when you iterate you are iterating through elements of a string, not elements of a list.
I am assuming that you are learning python. The current program works, but is not the best way to do it. You should try using csv or pickle. However, it is always good to start from basic! :D
students = []
info = []
name = input("Name: ")
age = input("Age: ")
info.append(name)
info.append(age)
students.append(info)
with open("file.txt", "a") as my_file:
for data in students:
my_file.write("%s,%s\n" % (data[0], data[1])) # this will write in file like name,age
After that you can retrieve like
search_keyword = input("Please Enter Student Name: ")
with open("file.txt", "r") as my_file:
for students in my_file:
for info in students.split(','): # We split it based on commas to get the desired output
print(info)
The mistake you were making is that when you tried for info in students you were iterating over characters in the string rather than the actual information.
Notice how we have used with open this will do all the file handling automatically.
Iterating over file-like objects produces lines
for students in my_file:
On each iteration students will be a line of text.
Iterating over text produces individual characters.
for info in students:
On each iteration info will be a character.
If your text files have string representations of python objects you can use ast.literal_eval to evaluate the objects.
import ast
with open('file.txt') as f:
for line in f:
thing = ast.literal_eval(line)
print(thing)
for item in thing:
print(item)
As mentioned in the docs, ast.literal_eval Safely evaluate an expression node or a string with emphasis on safe - it shouldn't evaluate destructive or unwanted Python statements.
You would be better off using one of the built-in data persistence modules or perhaps json or even xml to save your data.

Using user info from text file in Python

I have a file called data.txt with a student numbers and names:
123, Bobbie Smith
456, Suzie Lan
789, Alex Palmer
What i'm trying to achieve is printing these information in sentences like this:
Bobbbie Smith has student number: 123
Suzie lan has student number: 456
Alex Palmer has student number: 789
So what I tried to do is putting every line on data.txt in a seperate list inside a list using:
file = open("data.txt", "r")
studentInfo = file.readlines()
file.close()
lines = [[line] for line in studentInfo]
>>> print(lines)
[['123, Bobbie Smith\n'], ['456, Suzie Lan\n'], ['789, Alex Palmer']]
Is this to good direction or should I do this using a completely different way?
use csv to avoid strip lines.
import csv
with open('data.txt', 'r', encoding='utf-8') as csv_f:
reader = csv.reader(csv_f)
for line in reader:
print('{x[1]} has student number: {x[0]}'.format(x=line))
You don't want to use file as a variable name, as it is a function. So you basically override it (thanks #Mark Tolonen).
You can slightly modify it and use context manager to read the file, and using string.format print the data in a readable fashion
with open("data.txt", "r") as f:
lines = [line.split(',') for line in f.readlines()]
for s in lines:
print '{} has student number: {}'.format(s[1].strip(), s[0].strip())
Output:
Bobbie Smith has student number: 123
Suzie Lan has student number: 456
Alex Palmer has student number: 789
I'm striping new lines from line because print statement prints a new line by default for every iteration
one way is using the numpy library
import numpy as np
x, y = np.loadtxt("data.txt", dtype = str, delimiter = ',', unpack = True)
for (i,j) in zip(x,y):
print(j+" has student number: "+i)
Here's a couple of ways to achieve what you want using re:
If you don't need to store the processed lines and just wanna print the output directly:
with open("data.txt", "r") as f:
for l in f.readlines():
try:
age, name = re.findall(r'\s*(\d+),\s*(.*)', l)[0]
print('{} has student number: {}'.format(name, age))
except:
pass
If you want to store the processed lines as a list of tuples, maybe something like this would do it:
with open("data.txt", "r") as f:
lines = [v[0]
for v in [re.findall(r'\s*(\d+),\s*(.*)', l) for l in f.readlines()] if v]
for age, name in lines:
print('{} has student number: {}'.format(name, age))

Python sort text file in dictionary

I have a text file that looks something like this:
John Graham 2
Marcus Bishop 0
Bob Hamilton 1
... and like 20 other names.
Each name appears several times and with a different number(score) after it.
I need to make a list that shows each name only one time and with a sum of that name's total score efter it. I need to use a dictionary.
This is what i have done, but it only makes a list like the text file looked like from the beginning:
dict = {}
with open('scores.txt', 'r+') as f:
data = f.readlines()
for line in data:
nameScore = line.split()
print (nameScore)
I don't know how to do the next part.
Here is one option using defaultdict(int):
from collections import defaultdict
result = defaultdict(int)
with open('scores.txt', 'r') as f:
for line in f:
key, value = line.rsplit(' ', 1)
result[key] += int(value.strip())
print result
If the contents of scores.txt is:
John Graham 2
Marcus Bishop 0
Bob Hamilton 1
John Graham 3
Marcus Bishop 10
it prints:
defaultdict(<type 'int'>,
{'Bob Hamilton': 1, 'John Graham': 5, 'Marcus Bishop': 10})
UPD (formatting output):
for key, value in result.iteritems():
print key, value
My first pass would look like:
scores = {} # Not `dict`. Don't reuse builtin names.
with open('scores.txt', 'r') as f: # Not "r+" unless you want to write later
for line in f:
name, score = line.strip().rsplit(' ', 1)
score = int(score)
if name in scores:
scores[name] = scores[name] + score
else:
scores[name] = score
print scores.items()
This isn't exactly how I'd write it, but I wanted to be explicit enough that you could follow along.
use dictionary get:
dict = {}
with open('file.txt', 'r+') as f:
data = f.readlines()
for line in data:
nameScore = line.split()
l=len(nameScore)
n=" ".join(nameScore[:l-1])
dict[n] = dict.get(n,0) + int(nameScore[-1])
print dict
Output:
{'Bob Hamilton': 1, 'John Graham': 2, 'Marcus Bishop': 0}
I had a similar situation I was in. I modified Wesley's Code to work for my specific situation. I had a mapping file "sort.txt" that consisted of different .pdf files and numbers to indicate the order that I want them in based on an output from DOM manipulation from a website. I wanted to combine all these separate pdf files into a single pdf file but I wanted to retain the same order they are in as they are on the website. So I wanted to append numbers according to their tree location in a navigation menu.
1054 spellchecking.pdf
1055 using-macros-in-the-editor.pdf
1056 binding-macros-with-keyboard-shortcuts.pdf
1057 editing-macros.pdf
1058 etc........
Here is the Code I came up with:
import os, sys
# A dict with keys being the old filenames and values being the new filenames
mapping = {}
# Read through the mapping file line-by-line and populate 'mapping'
with open('sort.txt') as mapping_file:
for line in mapping_file:
# Split the line along whitespace
# Note: this fails if your filenames have whitespace
new_name, old_name = line.split()
mapping[old_name] = new_name
# List the files in the current directory
for filename in os.listdir('.'):
root, extension = os.path.splitext(filename)
#rename, put number first to allow for sorting by name and
#then append original filename +e extension
if filename in mapping:
print "yay" #to make coding fun
os.rename(filename, mapping[filename] + filename + extension)
I didn't have a suffix like _full so I didn't need that code. Other than that its the same code, I've never really touched python so this was a good learning experience for me.

How to parse txtfile and export into dictionary?

My task is to parse a txtfile and return a dictionary with the counts of last names in the file. The txtfile looks like this:
city: Aberdeen
state: Washington
Johnson, Danny
Williams, Steve
Miller, Austin
Jones, Davis
Miller, Thomas
Johnson, Michael
I know how to read the file in, and assign the file to a list or a string, however I have no clue how to go about finding the counts of each and putting them into a dictionary. Could one of you point me in the right direction?
import re
with open('test.txt') as f:
text = f.read()
reobj = re.compile("(.+),", re.MULTILINE)
dic = {}
for match in reobj.finditer(text):
surname = match.group()
if surname in dic:
dic[surname] += 1
else:
dic[surname] = 1
The result is:
{'Williams,': 1, 'Jones,': 1, 'Miller,': 2, 'Johnson,': 2}
In order to find the counts of each surname:
you need to create a dictionary, empty will do
loop through the lines in the file
for each line in the file determine what you need to do with the data, there appear to be headers. Perhaps testing for the presence of a particular character in the string will suffice.
for each line with that you decide is a name, you need to split or perhaps partition the string to extract the surname.
then using the surname as a key to the dictionary, check for and set or increment an integer as the key's value.
after you've looped through the file data, you should have a dictionary keyed by surname and values being the number of appearances.
import re
file = open('data.txt','r')
lastnames={}
for line in file:
if re.search(':',line) ==None:
line.strip()
last = line.split(',')[0].strip()
first = line.split(',')[1].strip()
if lastnames.has_key(last):
lastnames[last]+= 1
else:
lastnames[last]= 1
print lastnames
Gives me the following
>>> {'Jones': 1, 'Miller': 2, 'Williams': 1, 'Johnson': 2}
This would be my approach. No need to use regex. Also filtering blank lines for extra robustness.
from __future__ import with_statement
from collections import defaultdict
def nonblank_lines(f):
for l in f:
line = l.rstrip()
if line:
yield line
with open('text.txt') as text:
lines = nonblank_lines(text)
name_lines = (l for l in lines if not ':' in l)
surnames = (line.split(',')[0].strip() for line in name_lines)
counter = defaultdict(int)
for surname in surnames:
counter[surname] += 1
print counter
If you're using a Python version > 2.7 you could use the built in collections.Counter instead of a defaultdict.

I am having a problem with my python program that im running

From an input file I'm suppose to extract only first name of the student and then save the result in a new file called "student-­‐firstname.txt" The output file should contain a list of
first names (not include middle name). I was able to get delete of the last name but I'm having problem deleting the middle name any help or suggestion?
the student name in the file look something like this (last name, first name, and middle initial)
Martin, John
Smith, James W.
Brown, Ashley S.
my python code is:
f=open("studentname.txt", 'r')
f2=open ("student-firstname.txt",'w')
str = ''
for line in f.readlines():
str = str + line
line=line.strip()
token=line.split(",")
f2.write(token[1]+"\n")
f.close()
f2.close()
f=open("studentname.txt", 'r')
f2=open ("student-firstname.txt",'w')
for line in f.readlines():
token=line.split()
f2.write(token[1]+"\n")
f.close()
f2.close()
Split token[1] with space.
fname = token[1].split(' ')[0]
with open("studentname.txt") as f, open("student-firstname.txt", 'w') as fout:
for line in f:
firstname = line.split()[1]
print >> fout, firstname
Note:
you could use a with statement to make sure that the files are always closed even in case of an exception. You might need contextlib.nested() on old Python versions
'r' is a default mode for files. You don't need to specify it explicitly
.readlines() reads all lines at once. You could iterate over the file line by line directly
To avoid hardcoding the filenames you could use fileinput. Save it to firstname.py:
#!/usr/bin/env python
import fileinput
for line in fileinput.input():
firstname = line.split()[1]
print firstname
Example: $ python firstname.py studentname.txt >student-firstname.txt
Check out regular expressions. Something like this will probably work:
>>> import re
>>> nameline = "Smith, James W."
>>> names = re.match("(\w+),\s+(\w+).*", nameline)
>>> if names:
... print names.groups()
('Smith', 'James')
Line 3 basically says find a sequence of word characters as group 0, followed by a comma, some space characters and another sequence of word characters as group 1, followed by anything in nameline.
f = open("file")
o = open("out","w")
for line in f:
o.write(line.rstrip().split(",")[1].strip().split()+"\n")
f.close()
o.close()

Categories

Resources