max() arg is empty error when joining strings - python

I'm new to coding and I was trying to make a script that will join the tuples inside 'sl', which are a sequence of letters, into a new tuple called 's' with the items as strings. and then print out the longest string inside s.
this is the code I came up with (or short version). When I try to print the max item of 's' in this code, returns a
max() arg is empty
error.
sl = [['m','o','o','n'],['d','a','y'],['h','e','l','l','o']]
s = []
s = (''.join(i) for i in sl) # join the letters inside sl, put them into s
print(max(s, key=len)) # print longest string inside s
but I still can iterate throught s with:
for i in s:
print(i)
and will print the words inside s, joined
I suppose that (''.join(i) for i in sl) isnt properly joining them as strings. Is there a way that the words inside 's' are join as strings?

It works, just replace () with []
sl = [['m','o','o','n'],['d','a','y'],['h','e','l','l','o']]
s = []
s = [''.join(i) for i in sl]
print(s)
print(max(s, key=len))

Related

replace characters in a input text using lists

I wanna use lists;
by that I mean a = b in a list
let = {
"a", "b" (meaning a is b)
}
then how can I use this list to replace all characters in a input string
string = "stringa"
characters = [
"a", "b",
]
dic = {}
for l1 in zip(characters):
dic[l1]
result = ""
for letter in string:
result = result + dic[letter]
print(result)
input('Press Any Key To Exit')
I tried this but it didnt work any help is appeciarated
I think your problem is in the zip(characters) line.
you need more than one list inorder to zip.
When you do zip to just one list, the output is as seen here:
c = ['a','b']
for i in zip(c):
print(i)
# ('a',)
# ('b',)
and this also is what your error shows you KeyError: ('a',)
EDIT:
if you want to have "stringa" converted to "stringb" you have another issue.
What you need to do is:
string = "stringa"
dic = {'a':'b', 'b':'a'}
result = ""
for letter in string:
if letter in dic.keys():
letter = dic[letter]
result+=letter
print(result)
# stringb
When converting a list into a dictionary, you use slices to turn the list into two, for zipping together. zip returns a tuple iterator, so you need two for loop variables:
for l1, l2 in zip(characters[::2], characters[1::2]):
dic[l1] = l2
dic[l2] = l1
The [::2] gets every other character starting with the first one. The [1::2] gets every other character starting with the second one.
If you want to avoid a dictionary, and do a two-way replacement, then one way to do it is to do the replacements in the zip loop:
result = string
for l1, l2 in zip(characters[::2], characters[1::2]):
result = result.replace(l1, '#')
result = result.replace(l2, l1)
result = result.replace('#', l2)
The # is a temporary placeholder to avoid undoing the replacement we just did. You can set that to be any character that won't show up in the strings.

I Would Like To Replace A Word With A Letter In Python

Code:
list = ['hello','world']
list2 = ['a','b']
string = 'hello'# should output a
string_fin = ''
for s in string:
for i, j in zip (list, list2):
if s == i:
string_fin += j
print(string_fin)
I want to write hello or world in string = '' and to get the output a or b
I get which is nothing
The reason this is happening is because hello and world have more characters than a and b when I try something that has the same amount of characters as a or b it works
Please help
Thanks
Your program's main loop never runs because string is empty! So your program is basically:
list = ['hello','world']
list2 = ['a','b']
string = ''
string_fin = ''
print(string_fin)
Although based on how you worded your question, it is really hard to understand what you are trying to accomplish, but here is my go.
You have two lists: list1 and list2 (Please do not name your list list as it is a reserved keyword, use list1 instead!)
You want to check whether each word in your string matches with any word in your first list.
If it matches you want to take the corresponding word or letter from your second list, and append it into the string string_fin.
Finally, when you looped through all the words in the list, you print the content of string_fin.
The correct way to do this would be to split your string variable, and get each word stored in it.
string = 'hello or world'
stringWords = string.split()
Now, stringWords contains ['hello', 'or', 'world']. But I think you are not interested in the item or. So you can remove this item from the list, by using remove().
if 'or' in stringWords:
stringWords.remove('or')
Now you have the words that you are interested in. And we want to check whether any word in the first list matches with these words. (Remember, I renamed the first list from list to list1 to prevent any unexpected behavior.)
for word in stringWords:
tempIndex = list1.index(word)
temp = list2[tempIndex]
string_fin += temp
However, using index raises ValueError if a match is not found, so depending on your program logic, you may need to catch an exception and handle it.
The string string_fin will now contain ab or a or b depending on the value inside string.
Now, since you wanted to print something like a or b, you can instead create a list and store the matching words in it, and then, join this list using or separator.
string_fin = (' or ').join(tempList)
A complete program now will look like this:
list1 = ['hello', 'world']
list2 = ['a', 'b']
string = 'hello or world'
tempList = []
stringWords = string.split()
if 'or' in stringWords:
stringWords.remove('or')
for word in stringWords:
tempIndex = list1.index(word)
temp = list2[tempIndex]
tempList.append(temp)
string_fin = ' or '.join(tempList)
print(string_fin)
Better to store your lists as a dictionary, so you can do an easy lookup:
mapping = {'hello':'a', 'world':'b'}
string = 'hello or world'
out = []
for s in string.split():
out.append( mapping.get( s, s ) )
print(' '.join(out))
Purists will note that the for loop can be made into a one-liner:
mapping = {'hello':'a', 'world':'b'}
string = 'hello or world'
out = ' '.join(mapping.get(s,s) for s in string.split())
print(out)

Extract elements when a condition is met in different lines and storing them in one

I have elements in a list as:
temp_list = ["% Work\n"," Hard\n"," Or\n"," Go\n"," Home\n","%","% Happy Coding","%"]
I want to achieve this:
final_list = ["Work Hard Or Go Home","Happy Coding"]
The percentage sign in the elements is the separator between two comments of new lines.
Join the words and then split on %:
temp_list = ["% Work\n"," Hard\n"," Or\n"," Go\n"," Home\n","%","% Happy Coding","%"]
final_list = []
for line in map(str.strip, "".join(temp_list).split("%")):
if not line:
continue
final_list.append(line.replace("\n", ""))
print(final_list)
Prints:
['Work Hard Or Go Home', 'Happy Coding']
You can accomplish this using the iterators map, filter, and some string functions lstrip and replace
map takes a function and an iterator applies the function to every element and returns a new iterator
filter takes a function and an iterable, removes elements who do not return true
when its function is called on them.
lstrip remove whitespace from left side of string
replace(a,b) replaces a with b in string
flat = ""
# Make a normal string from your array
for elem in temp_list:
flat += elem
# First separate string by %
# Next filter out empty list elements
# Replace every \n with nothing and remove whitespace from left side.
your_groupings = list(
map(lambda el: el.replace("\n","").lstrip(),
filter(lambda el: len(el) != 0,
flat.split("%"))))
print(your_groupings)
> ['Work Hard Or Go Home', 'Happy Coding']
ls=[]
msg=""
for i in temp_list:
if i=="%":
ls.append (msg [1:].strip ().replace ("\n",""))
msg=""
else:
msg+=i
print(ls)
Here.. check for "%" if element is "%" then u need add msg to the list by removing spaces and replacing "\n" with "". Else append i to msg

Remove all words from a string that exist in a list

community.
I need to write a function that goes through a string and checks if each word exists in a list, if the word exists in the (Remove list) it should remove that word if not leave it alone.
i wrote this:
def remove_make(x):
a = x.split()
for word in a:
if word in remove: # True
a = a.remove(word)
else:
pass
return a
But it returns back the string with the (Remove) word still in there. Any idea how I can achieve this?
A more terse way of doing this would be to form a regex alternation based on the list of words to remove, and then do a single regex substitution:
inp = "one two three four"
remove = ['two', 'four']
regex = r'\s*(?:' + r'|'.join(remove) + ')\s*'
out = re.sub(regex, ' ', inp).strip()
print(out) # prints 'one three'
You can try something more simple:
import re
remove_list = ['abc', 'cde', 'edf']
string = 'abc is walking with cde, wishing good luck to edf.'
''.join([x for x in re.split(r'(\W+)', string) if x not in remove_list])
And the result would be:
' is walking with , wishing good luck to .'
The important part is the last line:
''.join([x for x in re.split(r'(\W+)', string) if x not in remove_list])
What it does:
You are converthing the string to list of words with re.split(r'(\W+)', string), preserving all the whitespaces and punctuation as list items.
You are creating another list with list comprehension, filtering all the items, which are not in remove_list
You are converting the result list back to string with str.join()
The BNF notation for list comprehensions and a little bit more information on them may be found here
PS: Of course, you may make this a little bit more readable if you break the one-liner into peaces and assign the result of re.split(r'(\W+)', string) to a variable and decouple the join and the comprehension.
You can create a new list without the words you want to remove and then use join() function to concatenate all the words in that list. Try
def remove_words(string, rmlist):
final_list = []
word_list = string.split()
for word in word_list:
if word not in rmlist:
final_list.append(word)
return ' '.join(final_list)
list.remove(x) returns None and modifies the list in-place by removing x it exists inside the list. When you do
a = a.remove(word)
you will be effectively storing None in a and this would give an exception in the next iteration when you again do a.remove(word) (None.remove(word) is invalid), but you don’t get that either since you immediately return after the conditional (which is wrong, you need to return after the loop has finished, outside its scope). This is how your function should look like (without modifying a list while iterating over it):
remove_words = ["abc", ...] # your list of words to be removed
def remove_make(x):
a = x.split()
temp = a[:]
for word in temp:
if word in remove_words: # True
a.remove(word)
# no need of 'else' also, 'return' outside the loop's scope
return " ".join(a)

How to join certain items in list

My list looks like this :
['', 'CCCTTTCGCGACTAGCTAATCTGGCATTGTCAATACAGCGACGTTTCCGTTACCCGGGTGCTGACTTCATACTT
CGAAGA', 'ACCGGGCCGCGGCTACTGGACCCATATCATGAACCGCAGGTG', '', '', 'AGATAAGCGTATCACG
ACCTCGTGATTAGCTTCGTGGCTACGGAAGACCGCAACAGGCCGCTCTTCTGATAAGTGTGCGG', '', '', 'ATTG
TCTTACCTCTGGTGGCATTGCAACAATGCAAATGAGAGTCACAAGATTTTTCTCCGCCCGAGAATTTCAAAGCTGT', '
TGAAGAGAGGGTCGCTAATTCGCAATTTTTAACCAAAAGGCGTGAAGGAATGTTTGCAGCTACGTCCGAAGGGCCACATA
', 'TTTTTTTAGCACTATCCGTAAATGGAAGGTACGATCCAGTCGACTAT', '', '', 'CCATGGACGGTTGGGGG
CCACTAGCTCAATAACCAACCCACCCCGGCAATTTTAACGTATCGCGCGGATATGTTGGCCTC', 'GACAGAGACGAGT
TCCGGAACTTTCTGCCTTCACACGAGCGGTTGTCTGACGTCAACCACACAGTGTGTGTGCGTAAATT', 'GGCGGGTGT
CCAGGAGAACTTCCCTGAAAACGATCGATGACCTAATAGGTAA', '']
Those are sample DNA sequences read from a file. The list can have various length, and one sequence can have 10 as well as 10,000 letters. In a source file, they are delimited by empty lines, hence empty items in list. How can I join all items in between empty ones ?
Try this, it's a quick and dirty solution that works fine, but won't be efficient if the input list is really big:
lst = ['GATTACA', 'etc']
[x for x in ''.join(',' if not e else e for e in lst).split(',') if x]
This is how it works, using generator expressions and list comprehensions from the inside-out:
',' if not e else e for e in lst : replace all '' strings in the list with ','
''.join(',' if not e else e for e in lst) : join together all the strings. Now the spaces between sequences will be separated by one or more ,
''.join(',' if not e else e for e in lst).split(',') : split the string at the points where there are , characters, this produces a list
[x for x in ''.join(',' if not e else e for e in lst).split(',') if x] : finally, remove the empty strings, leaving a list of sequences
Alternatively, the same functionality could be written in a longer way using explicit loops, like this:
answer = [] # final answer
partial = [] # partial answer
for e in lst:
if e == '': # if current element is an empty string …
if partial: # … and there's a partial answer
answer.append(''.join(partial)) # join and append partial answer
partial = [] # reset partial answer
else: # otherwise it's a new element of partial answer
partial.append(e) # add it to partial answer
else: # this part executes after the loop exits
if partial: # if one partial answer is left
answer.append(''.join(partial)) # add it to final answer
The idea is the same: we keep track of the non empty-strings and accumulate them, and whenever an empty string is found, we add all the accumulated values to the answer, taking care of adding the last sublist after the loop ends. The result ends up in the answer variable, and this solution only makes a single pass across the input.

Categories