I am trying to create a function that will continuous new lines based on a list in Python.
For example, I have a list:
I want my function to output this:
I have a function already however its output is wrong:
final_list = list()
for sentence in test:
if sentence != "\r\n":
print(sentence)
final_list.append(sentence)
else:
#Check if the next sentence is a newline as well
curr_idx = test.index(sentence)
curr_sentence = sentence
next_idx = curr_idx + 1
next_sentence = test[next_idx]
times = 0
while next_sentence == "\r\n":
times += 1
combine_newlines = next_sentence * times
next_idx += 1
next_sentence = test[next_idx]
continue
final_list.append(combine_newlines+ "\r\n")
Thank you very much!
You can use itertools.groupby to group consecutive items of the same value, and then join the grouped items for output:
from itertools import groupby
print([''.join(g) for _, g in groupby(test)])
test = [
'I will be out',
'I will have limited',
'\r\n',
'\r\n',
'\r\n',
'Thanks,',
'\r\n',
'Dave',
'\r\n',
'\r\n',
]
final_list = []
for e in test:
if e != '\r\n':
final_list.append(e)
else:
if len(final_list) == 0 or not final_list[-1].endswith('\r\n'):
final_list.append(e)
else:
final_list[-1] += e
prints
['I will be out', 'I will have limited', '\r\n\r\n\r\n', 'Thanks,', '\r\n', 'Dave', '\r\n\r\n']
Explanation: Iterate over your items e in test, if they are not equal to \r\n, simply append them to the final_list, otherwise either append them to final_list or extend the last element in final_list based on if it ends with \r\n.
Related
I'm doing an assignment where we have to write a comma code as described from the book
Say you have a list value like this:
spam = ['apples', 'bananas', 'tofu', 'cats']
Write a function that takes a list value as an argument and returns a string with all the items separated by a comma and a space, with and inserted before the last item. For example, passing the previous spam list to the function would return apples, bananas, tofu, and cats. But your function should be able to work with any list value passed to it.
We are to write it with these details:
In your program, create four lists as follows:
animalList1 = ['dog', 'cat', 'bird', 'tiger', 'lion', 'camel']
animalList2 = ['elephant', 'alligator']
animalList3 = ['horse']
animalList4 = []
When you run your program, pass each list to the commaCode() function and then print out the result as shown in the Example Output.
I'm really stuck and don't know if I'm heading in the right direction. This is my code so far:
animalList1 = ['dog', 'cat', 'bird', 'tiger', 'lion', 'camel']
animalList2 = ['elephant', 'alligator']
animalList3 = ['horse']
animalList4 = []
spam = [animalList1, animalList2, animalList3, animalList4]
def commacode(list):
spam[-1] = 'and ' + str(spam-[1])
for i in range(len(spam)-1):
spam[i] = str(spam[i]) + ','
stringList = ''
for i in range(len(spam)):
stringList = stringList + str(spam[i])
print(stringList)
print(commacode(spam))
This code also works. Firstly, you have 4 lists in the spam list. So you need to iterate over it. That is what the last 2 lines do. Each time a list is passed as a parameter to the commacode function. According to your expectations, the length of the list is identified to check if the length is 1. If the length is 1 it means there is one item. So that is printed out. If the length is 0 nothing is done. If the length is not zero then items in the list are iterated and concatenated to the string with a comma. Every item is checked on whether it is the last item. If it is the last item, the string will contain and as well.
from varname import nameof
animalList1 = ['dog', 'cat', 'bird', 'tiger', 'lion', 'camel']
animalList2 = ['elephant', 'alligator']
animalList3 = ['horse']
animalList4 = []
spam = [animalList1, animalList2, animalList3, animalList4]
name_of_list = [nameof(animalList1), nameof(animalList2), nameof(animalList3), nameof(animalList4)]
string = ""
counter = 0
def commacode(list, list_name):
global string
length = len(list)
if length == 1:
string = list[0]
elif length != 0:
for item in list:
if list.index(item) == length-1:
string = string + "and " + str(item)
else:
string = string + str(item) + ", "
else:
string = "-"
print(f"{list_name}: {string}")
string = ""
for list in spam:
commacode(list, name_of_list[counter])
counter += 1
The output that I got:
animalList1: dog, cat, bird, tiger, lion, and camel
animalList2: elephant, and alligator
animalList3: horse
animalList4: -
def foo(mylist):
if len(mylist) == 0:
return ""
elif len(mylist) == 1:
return mylist[0]
else:
return ", ".join(mylist[:-1]) + " and " + mylist[-1]
you need to add exception cases.
using .join makes things easy.
learn about join here:
https://www.geeksforgeeks.org/join-function-python/
learn about list indexing and slicing here:
https://towardsdatascience.com/the-basics-of-indexing-and-slicing-python-lists-2d12c90a94cf
I assume that you are not allowed to use join here. You must first take care of special cases for empty lists and singletons, then add all elements with another special processing for the last one.
Here is a possible Python code:
def commacode(lst):
# an empty list gives a blank string
if len(lst) == 0:
cr = ''
# a single element list returns its element
elif len(lst) == 1:
cr = lst[0]
# else all elements are joined with ' ,' except last with ', and'
else:
cr = lst[0]
# list has at least 2 elements so list[1:-1] is defined
# (it is at least empty for just 2 elements)
for elt in lst[1:-1]:
cr += ', ' + elt
# special processing for the last element
cr += ', and ' + lst[-1]
return cr
for lst in spam:
print(commacode(lst))
With your data, it gives as expected:
dog, cat, bird, tiger, lion, and camel
elephant, and alligator
horse
>>>
(I have added a prompt display make the last empty line visible)
If you can use join, the else part could be:
else:
# list has at least 2 elements so list[1:-1] is defined
# (it is at least empty for just 2 elements)
cr = ', '.join(lst[:-1]
# special processing for the last element
cr += ', and ' + lst[-1]
I am very new to programming, so sorry for a basic question. I am trying to write a function that will take a string in which words are divided by ',' and return a list of these words (the Split method). My code is:
def str_to_list(my_shop_str):
my_shop_list = ['']
word_in_list = 0
for letter in my_shop_str:
if letter != ',':
my_shop_list[word_in_list] += letter
else:
word_in_list += 1
my_shop_list + ['']
return my_shop_list
print(str_to_list("Milk,Cottage,Tomatoes")) should look like [Milk, Cottage, Tomatoes]
but I am keep getting IndexError: list index out of range.
I read some answers here and couldn't find something to work.
Can anyone explain what is wrong.
list has the method append so a solution will be something like this:
def str_to_list(my_shop_str):
my_shop_list = ['']
word_in_list = 0
for letter in my_shop_str:
if letter != ',':
my_shop_list[word_in_list] += letter
else:
word_in_list += 1
my_shop_list.append('')
return my_shop_list
PS: Do not forgot about empty spaces between words in string like "aaa, bbb, ccc" will be ['aaa', ' bbb', ' ccc'] with spaces.
def sp(s):
l =[]
while True:
comma = s.find(',')
if comma == -1:
l.append(s)
break
l.append(s[:comma])
s = s[comma+1:]
print(l)
this is a simplified version hope it helps.
Simplest Way:
We can use an inbuilt split function.
def Convert(string):
# split the string whenever "," occurs
# store the splitted parts in a list
li = list(string.split(","))
return li
# Driver code
str1 = "Hello,World"
print(Convert(str1))
Output:
["Hello", "World"]
In Python, I want to add a space to each string in the list. The result is irrelevant whether it is a string or a list. But I would like to get the number of all cases where there can be spaces in the string.
first, I tried like this, Make string to list.
sent = 'apple is good for health'
sent.split(' ')
sentence = []
b = ''
for i in sent:
c = ''
for j in sent[(sent.index(i)):]:
c += j
sentence.append((b+' '+c).strip())
b += i
sentence
In this case, the result obtain a string that contains only one space.
I also tried
for i in range(len(sent)):
sent[i:i] = [' ']
and another try is used ' '.join(sent[i:])
but the results are same.
how can I get
'apple isgoodforhealth', 'appleis goodforhealth', 'appleisgood forhealth', 'appleisgoodfor health', 'appleis goodfor health', 'apple isgood forhealth', 'appleisgood forhealth' ...
like this?
I really want to get the number of all cases.
My take on the problem utilizing itertools.combinations.
import itertools
sent = 'apple is good for health'
sent = sent.split(' ')
# Get indices for spaces
N = range(len(sent) - 1)
for i in N:
# Get all combinations where the space suits
# Note that this doesn't include the option of no spaces at all
for comb in itertools.combinations(N, i + 1):
# Add space to the end of each word
# with index contained in the combination
listsent = [s + " " if j in comb else s for j, s in enumerate(sent)]
# Make the result a string or count the combinations if you like
tempsent = "".join(listsent)
print(tempsent)
Use Join:-
sent = 'apple is good for health'
sent = sent.split(' ')
start_index = 0
last_index = len(sent)
for i in range(len(sent)-1):
first_word = "".join(sent[start_index:i+1])
second_word = "".join(sent[i+1:last_index])
print(first_word, " ", second_word)
Hope the above code will give output your way i.e, 'apple
isgoodforhealth', 'appleis goodforhealth', 'appleisgood forhealth etc.
This is the input given John plays chess and l u d o. I want the output to be in this format (given below)
John plays chess and ludo.
I have tried Regular expression for removing spaces
but doesn't work for me.
import re
sentence='John plays chess and l u d o'
sentence = re.sub(r"\s+", "", sentence, flags=re.UNICODE)
print(sentence)
I expected the output John plays chess and ludo. .
But the output I got is Johnplayschessandludo
This should work! In essence, the solution extracts the single characters out of the sentence, makes it a word and joins it back to the remaining sentence.
s = 'John plays chess and l u d o'
chars = []
idx = 0
#Get the word which is divided into single characters
while idx < len(s)-1:
#This will get the single characters around single spaces
if s[idx-1] == ' ' and s[idx].isalpha() and s[idx+1] == ' ':
chars.append(s[idx])
idx+=1
#This is get the single character if it is present as the last item
if s[len(s)-2] == ' ' and s[len(s)-1].isalpha():
chars.append(s[len(s)-1])
#Create the word out of single character
join_word = ''.join(chars)
#Get the other words
old_words = [item for item in s.split() if len(item) > 1]
#Form the final string
res = ' '.join(old_words + [join_word])
print(res)
The output will then look like
John plays chess and ludo
Above code won't maintain the sequence of words while solving the problem.
For example, try entering this sentence "John plays c h e s s and ludo"
Try using this instead if you have single word with whitespaces in the text at any position:
sentence = "John plays c h e s s and ludo"
sentence_list = sentence.split()
index = [index for index, item in enumerate(sentence_list) if len(item) == 1]
join_word = "".join([item for item in sentence_list if len(item) == 1])
if index != []:
list(map(lambda x: sentence_list.pop(index[0]), index[:-1]))
sentence_list[index[0]] = join_word
sentence = " ".join(sentence_list)
else:
sentence
I have a very messy data I am noticing patterns where ever there is '\n' end of the element, it needs to be merged with single element before that.
sample list:
ls = ['hello','world \n','my name','is john \n','How are you?','I am \n doing well']
ls
return/tryouts:
print([s for s in ls if "\n" in s[-1]])
>>> ['world \n', 'is john \n'] # gave elements that ends with \n
How do I get it elements that ends with '\n' merge with 1 before element? Looking for a output like this one:
['hello world \n', 'my name is john \n', 'How are you?','I am \n doing well']
If you are reducing a list, maybe, one readable approach is to use reduce function.
functools.reduce(func, iter, [initial_value]) cumulatively performs an operation on all the iterable’s elements and, therefore, can’t be applied to infinite iterables.
First of all, you need a kind of struck to accumulate results, I use a tuple with two elements: buffer with concatenated strings until I found "\n" and the list of results. See initial struct (1).
ls = ['hello','world \n','my name','is john \n','How are you?','I am \n doing well']
def combine(x,y):
if y.endswith('\n'):
return ( "", x[1]+[x[0]+" "+y] ) #<-- buffer to list
else:
return ( x[0]+" "+y, x[1] ) #<-- on buffer
t=reduce( combine, ls, ("",[]) ) #<-- see initial struct (1)
t[1]+[t[0]] if t[0] else t[1] #<-- add buffer if not empty
Result:
['hello world \n', 'my name is john \n', 'How are you? ', 'I am \n doing well ']
(1) Explained initial struct: you use a tuple to store buffer string until \n and a list of already cooked strings:
("",[])
Means:
("__ buffer string not yet added to list __", [ __result list ___ ] )
I wrote this out so it is simple to understand instead of trying to make it more complex as a list comprehension.
This will work for any number of words until you hit a \n character and clean up the remainder of your input as well.
ls_out = [] # your outgoing ls
out = '' # keeps your words to use
for i in range(0, len(ls)):
if '\n' in ls[i]: # check for the ending word, if so, add it to output and reset
out += ls[i]
ls_out.append(out)
out = ''
else: # otherwise add to your current word list
out += ls[i]
if out: # check for remaining words in out if total ls doesn't end with \n
ls_out.append(out)
You may need to add spaces when you string concatenate but I am guessing that it is just with your example. If you do, make this edit:
out += ' ' + ls[i]
Edit:
If you want to only grab the one before and not multiple before, you could do this:
ls_out = []
for i in range(0, len(ls)):
if ls[i].endswith('\n'): # check ending only
if not ls[i-1].endswith('\n'): # check previous string
out = ls[i-1] + ' ' + ls[i] # concatenate together
else:
out = ls[i] # this one does, previous didn't
elif ls[i+1].endswith('\n'): # next one will grab this so skip
continue
else:
out = ls[i] # next one won't so add this one in
ls_out.append(out)
You can solve it using the regex expression using the 're' module.
import re
ls = ['hello','world \n','my name','is john \n','How are you?','I am \n doing well']
new_ls = []
for i in range(len(ls)):
concat_word = '' # reset the concat word to ''
if re.search(r"\n$", str(ls[i])): # matching the \n at the end of the word
try:
concat_word = str(ls[i-1]) + ' ' + str(ls[i]) # appending to the previous word
except:
concat_word = str(ls[i]) # in case if the first word in the list has \n
new_ls.append(concat_word)
elif re.search(r'\n',str(ls[i])): # matching the \n anywhere in the word
concat_word = str(ls[i])
new_ls.extend([str(ls[i-1]), concat_word]) # keeps the word before the "anywhere" match separate
print(new_ls)
This returns the output
['hello world \n', 'my name is john \n', 'How are you?', 'I am \n doing well']
Assuming the first element doesn't end with \n and all words are longer than 2 characters:
res = []
for el in ls:
if el[-2:] == "\n":
res[-1] = res[-1] + el
else:
res.append(el)
Try this:
lst=[]
for i in range(len(ls)):
if "\n" in ls[i][-1]:
lst.append((ls[i-1] + ' ' + ls[i]))
lst.remove(ls[i-1])
else:
lst.append(ls[i])
lst
Result:
['hello world \n', 'my name is john \n', 'How are you?', 'I am \n doing well']