string appears as subset of character in list element python - python-3.x

So far, I have:
my_list = ['hello', 'oi']
comparison_list = ['this hellotext', 'this oitext']
for w in my_list:
if w in comparison_list: print('yes')
However, nothing prints because no element in my_list equals any element in comparison_list.
So how do I make this check as a subset or total occurance?
Ideal output:
yes
yes

You are checking the occurrence of the complete string in the list currently. Instead you can check for the occurrence of the string inside each comparison string and make a decision. A simple approach will be to re-write the loop as below
for w in my_list:
# Check for every comparison string. any() considers atleast 1 true value
if any([True for word in comparison_list if w in word]):
print('yes')

It's because you're comparing w to the list elements. If you wanna find w in each string in your comparison_list you can use any:
my_list = ['hello', 'oi', 'abcde']
comparison_list = ['this hellotext', 'this oitext']
for w in my_list:
if any(w in s for s in comparison_list):
print('yes')
else:
print('no')
I added a string to your list and handle the 'no' case in order to get an output for each element
Output:
yes
yes
no

Edited Solution:
Apologies for older solution, I was confused somehow.
Using re module , we can use re.search to determine if the string is present in the list of items. To do this we can create an expression using str.join to concatenate all the strings using |. Once the expression is created we can iterate through the list of comparison to be done. Note | means 'Or', so any of the searched strings if present should return bool value of True. Note I am assuming there are no special characters present in the my_list.
import re
reg = '|'.join(my_list)
for item in comparison_list:
print(bool(re.search(reg, item)))

Related

How to slice a list of strings till index of matched string depending on if-else condition

I have a list of strings =
['after','second','shot','take','note','of','the','temp']
I want to strip all strings after the appearance of 'note'.
It should return
['after','second','shot','take']
There are also lists which does not have the flag word 'note'.
So in case of a list of strings =
['after','second','shot','take','of','the','temp']
it should return the list as it is.
How to do that in a fast way? I have to repeat the same thing with many lists with unequal length.
tokens = [tokens[:tokens.index(v)] if v == 'note' else v for v in tokens]
There is no need of an iteration when you can slice list:
strings[:strings.index('note')+1]
where s is your input list of strings. The end slice is exclusive, hence a +1 makes sure 'note' is part.
In case of missing data ('note'):
try:
final_lst = strings[:strings.index('note')+1]
except ValueError:
final_lst = strings
if you want to make sure the flagged word is present:
if 'note' in lst:
lst = lst[:lst.index('note')+1]
Pretty much the same as #Austin's answer above.

How to delete substring from a list and have a full string of it present in list?

I have a python list having many sub-strings of a full string including the full string. Can someone help me to remove all the sub-strings from the list and have only full string.
lists = ['ab','bcd','cd','abcd','ef']
For the above input, i want the output to be as:
lists = ['abcd','ef']
Please note, not to consider the string length from this example since my actual list items length is much fluctuating.
This is not python code, but my algorithm. Hope it works
Let have 2 arrays, array1 for input and array2 for result
Find longest length element in array
For each element in array1, check with shorter elements:
if included [duplicate] -> Remove
if not keep
Add this long element in new array2 and
remove from array1
For those kept elements
Do step 2 again until finish
if only 1 element left in array1
. just add it to array2
import copy
listA = ['abc','bcd','abcd', 'ef', 'eef']
listB=copy.deepcopy(listA) # create 2nd copy of main list
new_list=[]
global longest_str
longest_str=max(listA, key=len)
l_len=len(listA)
while l_len>0:
for l in listB:
if l in longest_str and len(l)<len(longest_str):
listA.remove(l) # remove the sub-string
if longest_str == l:
new_list.append(l) #append longest string in new_list
listA.remove(l) #remove from the main list
l_len=len(listA)
if l_len>0:
longest_str=max(listA, key=len)
print(new_list)

How to remove marks from string and turn it into a list

I need to create a function that turns the string to a list without !?., %#$ . and without capital letters. The string at the end is just an example so it needs to return ['mr', 'stark', 'i', "don't", 'feel', 'so', 'good']
Can someone tell me why my code prints None?
def sentence_to_words(s):
# Write the rest of the code for question 2 below here.
s_new= []
s1 = s.split()
a = ['#',',','!','.','?','$']
for i in s.split():
if i in a:
s2 = s1.remove(i)
s_new = s_new.append(s2)
return s_new
print sentence_to_words("Mr. Stark... I don't feel so good")
The best way to debug this is to validate that your assumptions about program state hold on each step. Don't jump ahead until you're sure each line of code does what you expect. Adding a print inside your loop shows exactly what i is on each iteration:
Mr.
Stark...
I
don't
feel
so
good
None of these words are in a = ['#',',','!','.','?','$'], so the conditional block inside your loop never runs. After the loop is exhausted, your program returns None which Python functions return when no return value is specified.
Furthermore, your conditional block operations aren't working as you expect; check return values and avoid making assignments if they're an in-place operation such as .append(), which returns None and should not be assigned to anything. Also, if the if block does execute, it'll prematurely return the result without finishing work on the rest of the list.
You may be looking for something like this:
def sentence_to_words(s):
s_new = []
ignore = ["#", "!", ",", ".", "?", "$"]
for word in s.split():
cleaned_word = ""
for letter in list(word):
if letter not in ignore:
cleaned_word += letter
s_new.append(cleaned_word.lower())
return s_new
print sentence_to_words("Mr. Stark... I don't feel so good")
Output:
['mr', 'stark', 'i', "don't", 'feel', 'so', 'good']
The approach in the above example is to iterate over words, then iterate over letters in each word to clean them according to the requirements and add the clean word to the result array. Note the descriptive variable names, which aid in understanding the program (for example, i was actually a word in your code, but i usually means integer or index).
The above example can be optimized--it uses a lot of error-prone arrays and loops, the ignore list should be a parameter to make the function reusable, and the in operator is slow on lists (ignore should be a set). Using regex makes it a one-liner:
import re
def sentence_to_words(s):
return re.sub(r"[\#\,\!\.\?\$]", "", s).lower().split()
Or using filter and the list of characters to ignore as a default parameter:
def sentence_to_words(s, ignore=set("#!,.?$")):
return filter(lambda x: x not in ignore, s).lower().split()
Try it!
I couldn't understand your code very well, but where's an alternative using re.sub and split().
We first remove any special chars with re.sub an then use split to get a list of words, i.e.:
import re
sentence = "Mr. Stark... I don't feel so good"
words = re.sub(r"[#,!\?\$.]", "", s).split()
Using re.split:
words = re.split("[^a-z'-]+", sentence, 0, re.IGNORECASE)
Both examples output:
# ['Mr', 'Stark', 'I', 'don't', 'feel', 'so', 'good']
Ideone Demo

How can I make my program recognize if item is a string or an intiger?

I'm doing some python challenges for fun and I've found a challenge which tells me to make a program that takes an input and prints the numbers in the message.
but when I run the program it prints nothing but [] in the same number as the letters in the message, and also it do not recognize if a letter is actually a number or not, it just see every letter as a string and prints empty squares.
Here's the code:
WORDS = []
NUMBERS = []
Sentence = input()
for item in Sentence:
if item == str():
WORDS.append(item)
if item == int():
NUMBERS.append(item)
print(('[%s]' % ', '.join(map(str, NUMBERS))))
Have any ideas?
Here is probably what you meant. You have to split the sentence first.
All of the resulting items will be of type string, therefore isinstance will not help.
str.isdigit() checks if a string contains only digits. If it is a number, you can convert it to an integer using int.
WORDS = []
NUMBERS = []
Sentence = input()
for item in Sentence.split():
if item.isdigit():
NUMBERS.append(int(item))
else:
WORDS.append(item)
print(('[%s]' % ', '.join(map(str, NUMBERS))))
If you do not do the split first, it will work too, but give you just single characters in the WORDS list and single numbers in the NUMBERS list.
Typechecking is usually done using isinstance(obj, cls) :
x = 42
print(isinstance(x, int))
print(isinstance(x, str))
but in your case this will not work since input() always returns a string (a string composed of numeric characters is still a string), so the proper solution is to check if the string is composed only of numeric characters (and eventually build an int from it if you need proper ints).
Also, input() returns a single string, and from your namings (WORDS) I assume you want to iterate on the distinct words, not on each characters like you actually do:
words = []
numbers = []
sentence = input()
for item in sentence.strip().split():
if item.isnumeric():
numbers.append(int(item))
else:
words.append(item)
print(('[%s]' % ', '.join(map(str, numbers))))
Use the built-in isinstance function:
if isinstance(item, str):
WORDS.append(item)
if isinstance(item, int):
NUMBERS.append(item)

Find characters inside strings from the elements of a list in python

I just started to use python 3. I want to find specific characters inside a string that is part of a list. Here is my code:
num = ["one","two","threex"]
for item in num:
if item.find("x"):
print("found")
So, I want to print "found" if the character "x" is inside of one of the elements of the list. But when I run the code, it prints 3 times instead of one.
Why is printing 3 times? Can someone help me?
find() returns -1 if the character is not found in the string. Anything that is not zero is equal to True. try if item.find("x") > -1.
You can use in again for strings:
num = ["one","two","threex"]
for item in num:
if "x" in item:
print("found")
Think in Strings as a list of chars like "ext" -> ['e', 'x', 't']
so "x" in "extreme" is True
find returns Index if found and -1 otherwise.
num = ["one","two","threex"]
for item in num:
if item.find("x"):
print item.find("x")
i hope that you got the solution from above post ,here you know the reason why
You need to break out of looping through the strings if 'x' is found as otherwise, it may be found in other strings. Also, when checking if 'x' is in the string, use in instead.
num = ["one","two","threex"]
for item in num:
if "x" in item:
print("found")
break
which outputs:
found
And if I modify the num list so that it has no x in any of the elements:
num = ["one","two","three"]
then there is no output when running the code again.
But why was it printing 3 times before?
Well simply, using item.find("x") will return an integer of the index of 'x' in the string. And the problem with evaluating this with an if-statement is that an integer always evaluates to True unless it is 0. This means that every string in the num list passed the test: if item.find("x") and so for each of the 3 strings, found was printed. In fact, the only time that found wouldn't be printed would be if the string began with an 'x'. In which case, the index of 'x' would be 0 and the if would evaluate to False.
Hope this clears up why your code wasn't working.
Oh, and some examples of testing the if:
>>> if 0:
... print("yes")
...
>>> if 1:
... print("yes")
...
yes
>>> if -1:
... print("yes")
...
yes

Resources