Return multiple lists in Python - python

I have this part of a code:
def readTXT():
part_result = []
'''Reading all data from text file'''
with open('dataset/sometext.txt', 'r') as txt:
for lines in txt:
part = lines.split()
part_result = [int(i) for i in part]
#sorted([(p[0], p[14]) for p in part_result], key=lambda x: x[1])
print(part_result)
return part_result
And I'm trying to get all lists as a return, but for now I'll get only the first one, what is quite obvious, because my return is inside the for loop. But still, shouldn't the loop go through every line and return the corresponding list?
After doing research, all I found was return list1, list2 etc. But have should I manage it, if my lists will be generated from a text file line by line?
It frustates me, not being able to return multiple lists at once.

Here's my suggestion. Creating a 'major_array' and adding 'part_result' in that array on each iteration of loop. This way if your loop iterates 10 times, you will then have 10 arrays added in your 'major_array'. And finally the array is returned when the for loop finishes. :)
def readTXT():
#create a new array
major_array = []
part_result = []
'''Reading all data from text file'''
with open('dataset/sometext.txt', 'r') as txt:
for lines in txt:
part = lines.split()
part_result = [int(i) for i in part]
#sorted([(p[0], p[14]) for p in part_result], key=lambda x: x[1])
print(part_result)
major_array.append(part_result)
return major_array

Here is a solution:
def readTXT():
with open('dataset/sometext.txt') as lines:
all_lists = []
for line in lines:
all_lists.append([int(cell) for cell in line.split()])
return all_lists
Note that the return statement is outside of the loop. You get only one list because you return inside the loop.
For a more advanced user, this solution is a shorter and more efficient but at the cost of being a little hard to understand:
def readTXT():
with open('dataset/sometext.txt') as lines:
return [[int(x) for x in line.split()] for line in lines]

Related

I want to return a list of length of lines in a file, but my code isn't working

I want to return the length on each line as an element in a list named lst but
my code is not working, the output always comes to be an empty list. Please tell
me what's wrong with my code.
# this is the file
f = open("abcd.txt", 'w')
f.write("Hello How Ar3 you?")
f.write("\nHope You're doing fine")
f.write("\nI'm doing okay too.")
f.write("\nSizole!")
f.close()
This is the code I wrote to return a list of length of lines in the file:
f = open("abcd.txt", 'r')
t = f.readlines()
print(t)
lst = []
for line in f.readlines():
lst.append(len(line))
print(lst)
Output: lst == []
Just make it simple by reading the line once and do the length count.
below code is used list comprehension.
texts = f.readlines()
lst = [len(line) for line in texts]
print(lst)
Here's the output of the above code. Hope this helps and most of them had given the correct answers.
[19, 23, 20, 7]
When you read the file back in the second code snippet, the:
t = f.readlines()
...
reads the entire file in to list and assigns it to the variable t.
You then try to read all the lines again with the:
for line in f.readlines():
...
Which will not work because they have all been read already.
To fix it, just change the for loop to this:
for line in t:
You don't need to read the lines before the loop (that is the line t = ... is unnecessary).
In fact doing so is likely causing the problem - once you read the lines, the file pointer is at the end of the file so there's nothing left to read.
In your code, you are calling f.readlines() twice. You just need to call it once:
f = open("abcd.txt", 'r')
t = f.readlines()
print(t)
lst = []
# instead of for line in f.readlines(), we can simply use t
for line in t:
lst.append(len(line))
print(lst)
or if the variable t is not necessary:
f = open("abcd.txt", 'r')
lst = []
for line in f.readlines():
lst.append(len(line))
print(lst)
f.readlines() will move the file pointer to the end of file. Calling it again will return an empty list, which is not what we want.

python and iteration specifically "for line in first_names"

If I 'pop' an item off an array in python, I seem to shoot myself in the foot by messing up the array's total length? See the following example:
Also am I just being an idiot or is this normal behaviour? And is there a better way to achieve what I am trying to do?
first_names = []
last_names = []
approved_names = []
blacklisted_names = []
loopcounter = 0
with open("first_names.txt") as file:
first_names = file.readlines()
#first_names = [line.rstrip() for line in first_names]
for line in first_names:
line = line.strip("\r\n")
line = line.strip("\n")
line = line.strip(" ")
if line == "":
first_names.pop(loopcounter)
#first_names.pop(first_names.index("")) # Does not work as expected
#loopcounter -= 1 # Does not work as expected either......
loopcounter += 1
loopcounter = 0
def save_names():
with open("first_names2.txt",'wt',encoding="utf-8") as file:
file.writelines(first_names)
and the resulting files:
first_names.txt
{
Abbey
Abbie
Abbott
Abby
Abe
Abie
Abstinence
Acton
}
And the output file
{
Abbey
Abbie
Abbott
Abe
Abie
Abstinence
Acton
}
list.pop() removes an item from a list and returns the value (see e.g. this ref). For the very basic task of cleaning and writing the list of names, an easy edit would be:
with open("first_names.txt") as file:
first_names = file.readlines()
cleaned_lines = []
for line in first_names:
clean_l = line.strip("\r\n").strip("\n").strip(" ")
if clean_l != "":
cleaned_lines.append(clean_l)
with open("first_names2.txt",'wt',encoding="utf-8") as file:
file.writelines(cleaned_lines)
If you don't want to create a cleaned copy of the list first_names, you could iteratively append single lines to the file as well.
with open("first_names.txt") as file:
first_names = file.readlines()
with open("first_names2.txt",'wt',encoding="utf-8") as file:
for line in first_names:
clean_l = line.strip("\r\n").strip("\n").strip(" ")
if clean_l != "":
file.writelines([clean_l, ])
In general it is not a good idea to mutate a list on which you're iterating, as you stated in your question. If you pop an element from the list you don't necessarily mess up the array's length, but you may encounter unexpected behavior when dealing with which index to pop. In this case you may skip some elements of the array.
A quick solution would be to make a copy of the list and use the built-in enumerate() method as follows:
copy = first_names.copy()
for i, line in enumerate(copy):
line = line.strip("\r\n")
line = line.strip("\n")
line = line.strip(" ")
if line == "":
first_names.remove(i)
More on enumerate() here.
The usual practice would be to filter or create a new list, rather than change the list you are iterating. It's not uncommon to create a new list with the changes you want, and then just assign it back to the original variable name. Here is a list comprehension. Note the if statement that filters out the undesirable blank lines.
first_names = [name.strip() for name in first_names if name.strip()]
https://docs.python.org/3/glossary.html#term-list-comprehension
And you can do the same with iterators using map to apply a function to each item in the list, and filter to remove the blank lines.
first_names_iterator = filter(lambda x: bool(x), map(lambda x: x.strip(), first_names))
first_names = list(first_names_iterator)
https://docs.python.org/3/library/functions.html#map
https://docs.python.org/3/library/functions.html#filter
The last line demonstrates that you could have just passed the iterator to list's constructor to get a list, but iterators are better. You can iterate through them without having to have the whole list at once. If you wanted a list, you should use list comprehension.
The lambda notation is just a fast way to write a function. I could have defined a function with a good name, but that's often overkill for things like map, filter, or a sort key.
Full code:
test_cases = [
'Abbey',
' Abbie ',
'',
'Acton',
]
print(test_cases)
first_names = list(test_cases)
first_names = [name.strip() for name in first_names if name.strip()]
print(first_names)
first_names = list(test_cases)
for name in filter(lambda x: bool(x),
map(lambda x: x.strip(),
first_names)):
print(name)

Why won't this function append values from the textfile to my list?

def read1(file): #this function will read and extract the first column of values from the
with open(file,"r") as b: # text allowing us to access it later in our main function
list1 = list(b)
lines = b.readlines()
result1 = []
for i in lines:
result1.append(list1.split()[0])
b.close
return result1
x = read1("XRD_example1.txt")
Any errors clearly visible?
You do:
list1 = list(b)
lines = b.readlines()
but the first of those lines already reads up all contents of your file, there's nothing to be read in the second line.
def read1(file): #this function will read and extract the first column of values from the
with open(file,"r") as b: # text allowing us to access it later in our main function
lines = b.readlines()
result1 = []
for i in lines:
result1.append(i.split()[0])
# no need for close, when using 'with open()'
return result1
should work, or even better:
def read1(file):
with open(file,"r") as b:
return [i.split()[0] for i in b.readlines()]

I'm looking for a string in a file, seems to not be working

My function first calculates all possible anagrams of the given word. Then, for each of these anagrams, it checks if they are valid words, but checking if they equal to any of the words in the wordlist.txt file. The file is a giant file with a bunch of words line by line. So I decided to just read each line and check if each anagram is there. However, it comes up blank. Here is my code:
def perm1(lst):
if len(lst) == 0:
return []
elif len(lst) == 1:
return [lst]
else:
l = []
for i in range(len(lst)):
x = lst[i]
xs = lst[:i] + lst[i+1:]
for p in perm1(xs):
l.append([x] + p)
return l
def jumbo_solve(string):
'''jumbo_solve(string) -> list
returns list of valid words that are anagrams of string'''
passer = list(string)
allAnagrams = []
validWords = []
for x in perm1(passer):
allAnagrams.append((''.join(x)))
for x in allAnagrams:
if x in open("C:\\Users\\Chris\\Python\\wordlist.txt"):
validWords.append(x)
return(validWords)
print(jumbo_solve("rarom"))
If have put in many print statements to debug, and the passed in list, "allAnagrams", is fully functional. For example, with the input "rarom, one valid anagram is the word "armor", which is contained in the wordlist.txt file. However, when I run it, it does not detect if for some reason. Thanks again, I'm still a little new to Python so all the help is appreciated, thanks!
You missed a tiny but important aspect of:
word in open("C:\\Users\\Chris\\Python\\wordlist.txt")
This will search the file line by line, as if open(...).readlines() was used, and attempt to match the entire line, with '\n' in the end. Really, anything that demands iterating over open(...) works like readlines().
You would need
x+'\n' in open("C:\\Users\\Chris\\Python\\wordlist.txt")
if the file is a list of words on separate lines to make this work to fix what you have, but it's inefficient to do this on every function call. Better to do once:
wordlist = open("C:\\Users\\Chris\\Python\\wordlist.txt").read().split('\n')
this will create a list of words if the file is a '\n' separated word list. Note you can use
`readlines()`
instead of read().split('\n'), but this will keep the \n on every word, like you have, and you would need to include that in your search as I show above. Now you can use the list as a global variable or as a function argument.
if x in wordlist: stuff
Note Graphier raised an important suggestion in the comments. A set:
wordlist = set(open("C:\\Users\\Chris\\Python\\wordlist.txt").read().split('\n'))
Is better suited for a word lookup than a list, since it's O(word length).
You have used the following code in the wrong way:
if x in open("C:\\Users\\Chris\\Python\\wordlist.txt"):
Instead, try the following code, it should solve your problem:
with open("words.txt", "r") as file:
lines = file.read().splitlines()
for line in lines:
# do something here
So, putting all advice together, your code could be as simple as:
from itertools import permutations
def get_valid_words(file_name):
with open(file_name) as f:
return set(line.strip() for line in f)
def jumbo_solve(s, valid_words=None):
"""jumbo_solve(s: str) -> list
returns list of valid words that are anagrams of `s`"""
if valid_words is None:
valid_words = get_valid_words("C:\\Users\\Chris\\Python\\wordlist.txt")
return [word for word in permutations(s) if word in valid_words]
if __name__ == "__main__":
print(jumbo_solve("rarom"))

Cannot write sorted list into new file.

I'm trying to write a sorted list onto a file. I have 1000 integers that I've sorted in ascending order, but cannot manage to write the new list of ascending numbers into my new file 'results'. I am new to programming and any help would be greatly appreciated.
This is my code so far:
def insertion_sort():
f = open("integers.txt", "r")
lines = f.read().splitlines()
print(lines)
print(type(lines[0]))
results = list(map(int, lines))
print(type(results[0]))
results.sort()
print(results)
f=open("integers.txt", "r")
lines = f.read().splitlines()
results = list(map(int,lines))
insertion_sort()
value = results.sort()
file_to_save_to = open("results.txt", "w")
file_to_save_to.write(str(value))
file_to_save_to.close()
Your problem is from this line
value = results.sort()
the sort method of a list doesn't return anything, it modifies the list in place.
Instead you should use sorted
value = sorted(results)
or the list directly as results without storing the return value of it's sort method
results.sort()`
First of all, it would be great if you would change your function to receive a parameter (list of ints), and return sorted list instead of None (as it is right now)
def insertion_sort(T):
return sorted(T)
f=open("integers.txt", "r")
lines = f.read().splitlines()
results = list(map(int,lines))
value = insertion_sort(results)
file_to_save_to = open("results.txt", "w")
file_to_save_to.write(str(value))
file_to_save_to.close()
You should try to use function sorted
value = sorted(results)
And you may not use list(map(int, lines))) you can pass map object to the sorted, so code will be like this:
results = sorted(map(int,lines))
And full example will be like this:
f=open("integers.txt", "r")
lines = f.read().splitlines()
sorted_lines = sorted(map(int,lines))
file_to_save_to = open("results.txt", "w")
for line in sorted_lines:
file_to_save_to.write(str(line))
file_to_save_to.close()
You're calling insertion_sort() which is a function that performs the operation, but doesn't yet return anything. You'll want to return the results by simply adding the return statement at the end of your function:
def insertion_sort():
f = open("integers.txt", "r")
lines = f.read().splitlines()
print(lines)
print(type(lines[0]))
results = list(map(int, lines))
print(type(results[0]))
results.sort()
print(results)
return results # <- Add this line
Then, use the returned list by changing:
insertion_sort() to value = insertion_sort()

Categories

Resources