Misplaced and produced by a for loop - python-3.x

Totally new to programming. Working on the comma code example in Automate the boring stuff. The following code works (with some extra spaces I have to clean up). But on initialization, it prints the list correctly as in "The list is apples, bananas, tofu, and cats.
When you create a new list it does this instead: "The list is and, a, b, c, d."
# initializing list
test_list = ['apples', 'bananas', 'tofu', 'cats']
# printing original list
while True:
print('The list is ', end='')
for i in range(0, len(test_list)):
if i != (len(test_list)-1):
print(str(test_list[i]), ', ', end='')
if i == (len(test_list)-1):
print('and', str(test_list[i]), '.')
print('Write a new list that contains elements separated by a comma then space.')
test_list = [input()]

Your issue is the input is taking the full string and adding it as a single element to the test_list list. The string needs to be split.
The only thing that needs to be changed is the last line:
test_list = input().split(", ")
>>>test1, test2, test3
The list is test1 , test2 , and test3 .
As for cleaning up the extra spaces--concatenate the strings with + instead of ,.
Combining all code:
# initializing list
test_list = ['apples', 'bananas', 'tofu', 'cats']
# printing original list
while True:
print('The list is ', end='')
for i in range(0, len(test_list)):
if i != (len(test_list)-1):
print(str(test_list[i]) + ', ', end='')
if i == (len(test_list)-1):
print('and', str(test_list[i]) + '.')
print('Write a new list that contains elements separated by a comma then space.')
test_list = input().split(", ")
Results in the output: The list is test1, test2, and test3.
There are several other things I would write differently, but this should solve your problem. Take care!

Related

Python how to grep two keywords from a sting in a text file and append into two strings

DELIVERED,machine01,2022-01-20T12:57:06,033,Email [Test1] is delivered by [192.168.0.2]
Above is the content from the text file. I have used split(",") method but I have no idea how to make it works as below. Can anyone help with this?
'DELIVERED', 'machine01', '2022-01-20T12:57:06', '033', 'Test1', '192.168.0.2'
with open('log_file.log', 'r') as f:
for line in f.readlines():
sep = line.split(",")
print(sep)
text = "DELIVERED,machine01,2022-01-20T12:57:06,033,Email [Test1] is delivered by [192.168.0.2]"
result = []
for part in text.split(','): # loops the parts of text separated by ","
result.append(part) # appends this parts into a list
print(result) # prints this list:
['DELIVERED', 'machine01', '2022-01-20T12:57:06', '033', 'Email [Test1] is delivered by [192.168.0.2]']
# or you can do all the same work in just 1 line of code!
result = [part for part in text.split(',')]
print(result)
['DELIVERED', 'machine01', '2022-01-20T12:57:06', '033', 'Email [Test1] is delivered by [192.168.0.2]']
Once you have split using , you then need to use a regular expression to find the contents of the [] in the final string. Since you are doing this over multiple lines, we collect each list in a variable (fields) then print this list of lists at the end:
import re
fields = []
with open('log_file.log', 'r') as f:
for line in f.readlines():
sep = line.split(",")
# Get the last item in the list
last = sep.pop()
# Find the values in [] in last
extras = re.findall(r'\[(.*?)\]', last)
# Add these values back onto sep
sep.extend(extras)
fields.append(sep)
print(fields)
log_file.log:
DELIVERED,machine01,2022-01-20T12:57:06,033,Email [Test1] is delivered by [192.168.0.2]
DELIVERED,machine02,2022-01-20T12:58:06,034,Email [Test2] is delivered by [192.168.0.3]
Result:
[['DELIVERED', 'machine01', '2022-01-20T12:57:06', '033', 'Test1', '192.168.0.2'], ['DELIVERED', 'machine02', '2022-01-20T12:58:06', '034', 'Test2', '192.168.0.3']]

How to split strings from .txt file into a list, sorted from A-Z without duplicates?

For instance, the .txt file includes 2 lines, separated by commas:
John, George, Tom
Mark, James, Tom,
Output should be:
[George, James, John, Mark, Tom]
The following will create the list and store each item as a string.
def test(path):
filename = path
with open(filename) as f:
f = f.read()
f_list = f.split('\n')
for i in f_list:
if i == '':
f_list.remove(i)
res1 = []
for i in f_list:
res1.append(i.split(', '))
res2 = []
for i in res1:
res2 += i
res3 = [i.strip(',') for i in res2]
for i in res3:
if res3.count(i) != 1:
res3.remove(i)
res3.sort()
return res3
print(test('location/of/file.txt'))
Output:
['George', 'James', 'John', 'Mark', 'Tom']
Your file opening is fine, although the 'r' is redundant since that's the default. You claim it's not, but it is. Read the documentation.
You have not described what task is so I have no idea what's going on there. I will assume that it is correct.
Rather than populating a list and doing a membership test on every iteration - which is O(n^2) in time - can you think of a different data structure that guarantees uniqueness? Google will be your friend here. Once you discover this data structure, you will not have to perform membership checks at all. You seem to be struggling with this concept; the answer is a set.
The input data format is not rigorously defined. Separators may be commas or commas with trailing spaces, and may appear (or not) at the end of the line. Consider making an appropriate regular expression and using its splitting feature to split individual lines, though normal splitting and stripping may be easier to start.
In the following example code, I've:
ignored task since you've said that that's fine;
separated actual parsing of file content from parsing of in-memory content to demonstrate the function without a file;
used a set comprehension to store unique results of all split lines; and
used a generator to sorted that drops empty strings.
from io import StringIO
from typing import TextIO, List
def parse(f: TextIO) -> List[str]:
words = {
word.strip()
for line in f
for word in line.split(',')
}
return sorted(
word for word in words if word != ''
)
def parse_file(filename: str) -> List[str]:
with open(filename) as f:
return parse(f)
def test():
f = StringIO('John, George , Tom\nMark, James, Tom, ')
words = parse(f)
assert words == [
'George', 'James', 'John', 'Mark', 'Tom',
]
f = StringIO(' Han Solo, Boba Fet \n')
words = parse(f)
assert words == [
'Boba Fet', 'Han Solo',
]
if __name__ == '__main__':
test()
I came up with a very simple solution if anyone will need:
lines = x.read().split()
lines.sort()
new_list = []
[new_list.append(word) for word in lines if word not in new_list]
return new_list
with open("text.txt", "r") as fl:
list_ = set()
for line in fl.readlines():
line = line.strip("\n")
line = line.split(",")
[list_.add(_) for _ in line if _ != '']
print(list_)
I think that you missed a comma after Jim in the first line.
You can avoid the use of a loop by using split property :
content=file.read()
my_list=content.split(",")
to delete the occurence in your list you can transform it to set :
my_list=list(set(my_list))
then you can sort it using sorted
so the finale code :
with open("file.txt", "r") as file :
content=file.read()
my_list=content.replace("\n","").replace(" ", "").split(",")
result=sorted(list(set(my_list)))
you can add a key to your sort function

How do I print without square brackets

so I got this function here, and what it's supposed to do is create a file, that I can write in. the second and third parameters are lists, while the first is just the file name that I am going to create to write in. In the function, I made a for loop, and I'm looping through the all_students_list, which is a list, but at each index, is also a list, with the first name and last name in the list. all_courses_list is a list of all the courses in the school, and Schedule is a list that another function returns, giving us the schedule of the student. Then I added the student name and the schedule together, to write to the file. The problem is that it also prints [] square brackets. How can I get rid of it? I've already tried to do
.replace('[', '')
.replace(']', '')
But it doesn't work.
Here is my code.
def generate_student_schedules(filename, all_courses_list, all_students_list):
with open(filename,'w') as fileout:
for one_student in all_students_list:
schedule = get_schedule(all_courses_list)
one_line = ''
one_line += (f'{one_student}')
one_line += (f'{schedule}\n')
fileout.write(one_line)
If one_student is an actual list, then you can use " ".join(one_student), so overall:
def generate_student_schedules(filename, all_courses_list, all_students_list):
with open(filename,'w') as fileout:
for one_student in all_students_list:
schedule = get_schedule(all_courses_list)
one_line = ''
one_line += (" ".join(one_student))
one_line += (f'{schedule}\n')
fileout.write(one_line)
When you print a list, Python's default is to print the brackets and items in the list. You have to build a single string of the components of the list and print that single string. Your format string can pull out individual items or use join across all the items if they are all strings:
>>> student = ['John','Smith']
>>> schedule = ['Class1','Class2']
>>> print(student,schedule)
['John', 'Smith'] ['Class1', 'Class2']
>>> line = f'{student[1]}, {student[0]}: {", ".join(schedule)}'
>>> print(line)
Smith, John: Class1, Class2

Convert a string with components separated by symbols into a nested python dictionary

I'm struggling with a Python question and would appreciate any help. Do have patience, my Python is basic at the moment.
Question:
How do I transform a string structure like this:
text="key1=value1;key2=value2\nkeyA=valueA\n..."
into a Python dictionary like this:
{0:{'key1':'value1', 'key2':'value2'}, 1:{'keyA':'valueA'}}
Realize that ';' separates items in the inner dictionary while ā€˜\nā€™ separates items on the outer dictionary.
The key, values in the inner dictionaries are strings. The keys for the outer dictionaries are indexes.
There needs to be another function to transform this Python dictionary back into its original string form.
Where I am now:
I was thinking of creating a loop that is able to do this but I'm struggling to create it.
a[0]["key1"]="value1"
a[0]["key2"]="value2"
a[1]["keyA"]="valueA"
The best I did was to split the string by '\n' like this:
text ='k1=v1;k2=v2\nk3=v3\nk4=v4'
text = text.split("\n")
output: ['k1=v1;k2=v2', 'k3=v3', 'k4=v4']
And looped the elements into the dictionary like this:
dic = {}
for i,x in enumerate(text):
dic[i] = x
output: {0: 'k1=v1;k2=v2', 1: 'k3=v3', 2: 'k4=v4'}
But how do I get these values within the dictionary into the key, value structure as seen above?
You can use the following dict comprehension:
{i: dict(p.split('=', 1) for p in l.split(';')) for i, l in enumerate(text.split('\n')) if l}
With your sample input:
text="key1=value1;key2=value2\nkeyA=valueA\n"
This returns:
{0: {'key1': 'value1', 'key2': 'value2'}, 1: {'keyA': 'valueA'}}
There may be a more clean and precise way to solve your problem but for now, You can manage with this one.
def make_dict(string):
temp={}
string=string.split(';')
string=[i.split('=') for i in string]
for a,b in string:
temp[a]=b
return temp
text ='k1=v1;k2=v2\nk3=v3\nk4=v4'
text=text.split('\n')
dic={}
for i,x in enumerate(text):
dic[i] = make_dict(x)
>>> print(dic)
>>> {0: {'k1': 'v1', 'k2': 'v2'}, 1: {'k3': 'v3'}, 2: {'k4': 'v4'}}
If you want to reverse the above process then it can be done by the following way.
def convert_again(dct):
fetch_values = list(dct.values())
change_values_to_list = [list(i.items()) for i in fetch_values]
# add "=" in between the key-value pairs
for i in range(len(change_values_to_list)):
for j in range(len(change_values_to_list[i])):
change_values_to_list[i][j]='='.join(change_values_to_list[i][j])
# Now add ";"
answer = [';'.join(i) for i in change_values_to_list]
# Now add "\n"
final_answer = '\\n'.join(answer)
return final_answer
#Driver Code
dct= {0: {'k1': 'v1', 'k2': 'v2'}, 1: {'k3': 'v3'}, 2: {'k4': 'v4'}}
print(convert_again(dct)) # --> "k1=v1;k2=v2\nk3=v3\nk4=v4"
I've written a solution that can be extended for other examples as well.
I've created a more complicated example
Notice how, we have another set which is seperted by a ;. If I can demonstrate it for this example, it should work for others as well
It is important to note that this will work only if the last 2 characters in text is "\n". If "\n" is not present in the last two characters, then remove the line list1.remove("")
text="key3=value3;key4=value4\nkey1=value1;key2=value2\nkeyA=valueA\nkeyB=valueB\n"
I am first splitting by \n, that would mean that there would be an "" present in the list, since last 2 characters of text is "\n"
list1 = text.split("\n")
list1.remove("")
Now I'm creating two lists, one to append string separated by ";" and another to append strings NOT separated by ";"
list2 = [] #Stuff seperated by ;
list3 = [] #Stuff not seperated by ;
for items in list1:
if ';' in items:
list2.append(items)
else:
list3.append(items)
I created an empty dictionary which eventually have what you want:
result_dict = {} #To store all key, value pairs
list2 now has ['key3=value3;key4=value4', 'key1=value1;key2=value2']
#First storing key, value pairs seperated by ";"
for i in range(0, len(list2)):
a = list2[i].split(";")
result_dict[i] = dict(s.split('=') for s in a)
list3 has ['keyA=valueA', 'keyB=valueB']
#Now storing key, value pairs not seperated by ";"
nosemicolon_dict = dict(s.split('=') for s in list3)
for key, value in nosemicolon_dict.items():
for j in range(0, len(nosemicolon_dict)):
result_dict[j + i + 1] = {key:value}
FOR YOUR EXAMPLE, Run the same code above, replace text with your example also ensuring to take into account whether "\n" is the last two characters in your example or not. If you DON'T have "\n" at the end of the string, remove list1.remove("") THIS LINE
print(result_dict)
gave me:
{0: {'key1': 'value1', 'key2': 'value2'}, 1: {'keyA': 'valueA'}}

How to Read Multiple Files in a Loop in Python and get count of matching words

I have two text files and 2 lists (FIRST_LIST,SCND_LIST),i want to find out count of each file matching words from FIRST_LIST,SCND_LIST individually.
FIRST_LIST =
"accessorizes","accessorizing","accessorized","accessorize"
SCND_LIST=
"accessorize","accessorized","accessorizes","accessorizing"
text File1 contains:
This is a very good question, and you have received good answers which describe interesting topics accessorized accessorize.
text File2 contains:
is more applied,using accessorize accessorized,accessorizes,accessorizing
output
File1 first list count=2
File1 second list count=0
File2 first list count=0
File2 second list count=4
This code i have tried to achive this functionality but not able to get the expected output.
if any help appreciated
import os
import glob
files=[]
for filename in glob.glob("*.txt"):
files.append(filename)
# remove Punctuations
import re
def remove_punctuation(line):
return re.sub(r'[^\w\s]', '', line)
two_files=[]
for filename in files:
for line in open(filename):
#two_files.append(remove_punctuation(line))
print(remove_punctuation(line),end='')
two_files.append(remove_punctuation(line))
FIRST_LIST = "accessorizes","accessorizing","accessorized","accessorize"
SCND_LIST="accessorize","accessorized","accessorizes","accessorizing"
c=[]
for match in FIRST_LIST:
if any(match in value for value in two_files):
#c=match+1
print (match)
c.append(match)
print(c)
len(c)
d=[]
for match in SCND_LIST:
if any(match in value for value in two_files):
#c=match+1
print (match)
d.append(match)
print(d)
len(d)
Using Counter and some list comprehension is one of many different approaches to solve your problem.
I assume, your sample output being wrong since some words are part of both lists and both files but are not counted. In addition I added a second line to the sample strings in order to show how that is working with multi-line strings which might be the typical contents of a given file.
io.StringIO objects emulate your files, but working with real files from your file system works exactly the same since both provide a file-like object or file-like interface:
from collections import Counter
list_a = ["accessorizes", "accessorizing", "accessorized", "accessorize"]
list_b = ["accessorize", "accessorized", "accessorizes", "accessorizing"]
# added a second line to each string just for the sake
file_contents_a = 'This is a very good question, and you have received good answers which describe interesting topics accessorized accessorize.\nThis is the second line in file a'
file_contents_b = 'is more applied,using accessorize accessorized,accessorizes,accessorizing\nThis is the second line in file b'
# using io.StringIO to simulate a file input (--> file-like object)
# you should use `with open(filename) as ...` for real file input
file_like_a = io.StringIO(file_contents_a)
file_like_b = io.StringIO(file_contents_b)
# read file contents and split lines into a list of strings
lines_of_file_a = file_like_a.read().splitlines()
lines_of_file_b = file_like_b.read().splitlines()
# iterate through all lines of each file (for file a here)
for line_number, line in enumerate(lines_of_file_a):
words = line.replace('.', ' ').replace(',', ' ').split(' ')
c = Counter(words)
in_list_a = sum([v for k,v in c.items() if k in list_a])
in_list_b = sum([v for k,v in c.items() if k in list_b])
print("Line {}".format(line_number))
print("- in list a {}".format(in_list_a))
print("- in list b {}".format(in_list_b))
# iterate through all lines of each file (for file b here)
for line_number, line in enumerate(lines_of_file_b):
words = line.replace('.', ' ').replace(',', ' ').split(' ')
c = Counter(words)
in_list_a = sum([v for k,v in c.items() if k in list_a])
in_list_b = sum([v for k,v in c.items() if k in list_b])
print("Line {}".format(line_number))
print("- in list a {}".format(in_list_a))
print("- in list b {}".format(in_list_b))
# actually, your two lists are the same
lists_are_equal = sorted(list_a) == sorted(list_b)
print(lists_are_equal)

Resources