Python 3 How to find the different combinations of a String - python

Given a String is there any short way in Python 3 to find the different combinations of the space seperated words in that string ?
For eg:
If the input string is 'Peaches Apples Bananas', I want output as:
'Peaches Apples Bananas'
'Peaches Bananas Apples'
'Apples Bananas Peaches'
'Apples Peaches Bananas'
'Bananas Peaches Apples'
'Bananas Apples Peaches'

import itertools
string = 'Peaches Apples Bananas'
word_list = string.split(' ')
output = [' '.join(permutation) for permutation in itertools.permutations(word_list)]

I think you are looking for itertools.permutations:
import itertools
for perm in itertools.permutations('Peaches Apples Bananas'.split(' ')):
print(' '.join(perm))

Related

Is it possible to ignore string in quotes for replace()?

Is it possible to ignore string in quotes for python replace()?
I have a string variable like this:
a = "I like bananas 'I like bananas'"
I want to get a result like this via replace():
"I like apples 'I like bananas'".
But when I execute print(a.replace("bananas", "apples")),the result is:
"I like apples 'I like apples'".
How can I do to make replace() ignore string in quotes?
Split the string by ', process only the odd elements of the array, reassemble the string
a = "I like bananas 'I like bananas'"
ap = a.split("'")
ar = [ ai.replace("bananas", "apples") if i%2==0 else ai for i,ai in enumerate(ap)]
print("'".join(ar))
Here is regexp example:
import re
text = "I like bananas 'I like bananas' 'I like also bananas'"
def replace2(orginal_text, b, c):
pattern = re.compile(r".*? (\'.*?\')") # patternt to match text inside single quotes
matches = []
for match in pattern.findall(orginal_text): # match with pattern as many times pattern is found
matches.append(match)
for match in matches:
replace_with = match.replace(b, c) # replace b with c in matched string
orginal_text = re.sub(match, replace_with, orginal_text) # replace matched text with new string
return orginal_text
result = replace2(text, "bananas", "apples")
print(result)
It will try to foind all text that are between single quotes. Then replaces the old string (b) with new (c) from the matches. Finally replaces the new edited matches from original string.
No, it is not possible, you cannot make replace ignore those matches. You will have to code your own solution.
You can use count value (optional parameter of the replace method) to specify how many occurrences of the old value you want to replace.
It works fine for both.
a = "I like bananas \"I like bananas\""
print(a.replace("bananas", "apples",1))
a = "I like bananas 'I like bananas'"
print(a.replace("bananas", "apples",1))
Output:
I like apples 'I like bananas'
It's absolutely possible, this is complete answer for this question :
import re
original_str = "I like bananas 'I Love banana' somthing 'I like banana' I love banana ' I like babana again' "
pattern = r"('(.+?)')"
replaced_str = ''
quoted_strings = re.compile(pattern)
newstring = "foo"
x_start = 0
print("original_str = (", original_str+")\n")
for m in quoted_strings.finditer(original_str):
print(m.span(), m.group())
x_end, x_next = m.span()
w = original_str[x_start:x_end]
w = w.replace("banana", "apple")
replaced_str = replaced_str + w + original_str[x_end:x_next]
x_start = x_next
print(replaced_str)
output :
original_str = ( I like bananas 'I Love banana' somthing 'I like banana' I love banana ' I like babana again' )
(15, 30) 'I Love banana'
(42, 57) 'I like banana'
(73, 95) ' I like babana again'
I like apples 'I Love banana' somthing 'I like banana' I love apple ' I like babana again'
As per your update to your requirements in your reply to gnight
a = "I like bananas 'I like \'bananas\' ' "
print (a)
Gives:
I like bananas 'I like 'bananas' '
as the \' gets converted to ' when run,
that is it is the same as
a = "I like bananas 'I like 'bananas' ' "
as gnight says the only real option is to only replace in the first and last sections of the string that arent in quotes, Ie
a = "I like bananas 'I like \'bananas\' ' "
ap = a.split("'")
if len(ap)>0:
ap[0]=ap[0].replace("bananas", "apples")
if len(ap)>1:
ap[-1]=ap[-1].replace("bananas", "apples")
print("'".join(ap))
that gives:
I like apples 'I like 'bananas' '
In the past i have written parsers to handle tripple quote escaping that excel uses and a state machine to track the quote state, not fun to implement if you end up having to do that.If you can give some more examples of desired input an output it may help

How can I find an unknown word after a specific word?

I have this string "Hello, I bought apples, and sold bananas"
how can I get the value of the word after "bought" and the word after "sold" in python??
you can do this:
string = "Hello, I bought apples, and sold bananas"
string = string.replace(",","")
list_word = string.split(" ")
for i in range(len(list_word)):
if list_word[i]=="bought" or list_word[i]=="sold":
print(list_word[i+1])
output:
apples
bananas
There are several ways to do it. One way is to use regular expressions:
import re
s = "Hello, I bought apples, and sold bananas"
re.findall('\W(?:bought|sold)\W+(\w+)', s)

How to split sentences in a list?

I am trying to create a function to count the number of words and mean length of words in any given sentence or sentences. I can't seem to split the string into two sentences to be put into a list, assuming the sentence has a period and ending the sentence.
Question marks and exclamation marks should be replaced by periods to be recognized as a new sentence in the list.
For example: "Haven't you eaten 8 oranges today? I don't know if you did." would be: ["Haven't you eaten 8 oranges today", "I don't know if you did"]
The mean length for this example would be 44/12 = 3.6
def word_length_list(text):
text = text.replace('--',' ')
for p in string.punctuation + "‘’”“":
text = text.replace(p,'')
text = text.lower()
words = text.split(".")
word_length = []
print(words)
for i in words:
count = 0
for j in i:
count = count + 1
word_length.append(count)
return(word_length)
testing1 = word_length_list("Haven't you eaten 8 oranges today? I don't know if you did.")
print(sum(testing1)/len(testing1))
One option might use re.split:
inp = "Haven't you eaten 8 oranges today? I don't know if you did."
sentences = re.split(r'(?<=[?.!])\s+', inp)
print(sentences)
This prints:
["Haven't you eaten 8 oranges today?", "I don't know if you did."]
We could also use re.findall:
inp = "Haven't you eaten 8 oranges today? I don't know if you did."
sentences = re.findall(r'.*?[?!.]', inp)
print(sentences) # prints same as above
Note that in both cases we are assuming that period . would only appear as a stop, and not as part of an abbrevation. If period can have multiple contexts, then it could be tricky to tease apart sentences. For example:
Jon L. Skeet earned more point than anyone. Gordon Linoff also earned a lot of points.
It is not clear here whether period means end of sentence or part of an abbreviation.
An example to split using regex:
import re
s = "Hello! How are you?"
print([x for x in re.split("[\.\?\!]+",s.strip()) if not x == ''])

How to use backreferences as index to substitute via list?

I have a list
fruits = ['apple', 'banana', 'cherry']
I like to replace all these elements by their index in the list. I know, that I can go through the list and use replace of a string like
text = "I like to eat apple, but banana are fine too."
for i, fruit in enumerate(fruits):
text = text.replace(fruit, str(i))
How about using regular expression? With \number we can backreference to a match. But
import re
text = "I like to eat apple, but banana are fine too."
text = re.sub('apple|banana|cherry', fruits.index('\1'), text)
doesn't work. I get an error that \x01 is not in fruits. But \1 should refer to 'apple'.
I am interested in the most efficient way to do the replacement, but I also like to understand regex better. How can I get the match string from the backreference in regex.
Thanks a lot.
Using Regex.
Ex:
import re
text = "I like to eat apple, but banana are fine too."
fruits = ['apple', 'banana', 'cherry']
pattern = re.compile("|".join(fruits))
text = pattern.sub(lambda x: str(fruits.index(x.group())), text)
print(text)
Output:
I like to eat 0, but 1 are fine too.

How to extract a number before a certain words?

There is a sentence "i have 5 kg apples and 6 kg pears".
I just want to extract the weight of apples.
So I use
sentence = "I have 5 kg apples and 6 kg pears"
number = re.findall(r'(\d+) kg apples', sentence)
print (number)
However, it just works for integer numbers. So what should I do if the number I want to extract is 5.5?
You can try something like this:
import re
sentence = ["I have 5.5 kg apples and 6 kg pears",
"I have 5 kg apples and 6 kg pears"]
for sen in sentence:
print re.findall(r'(\d+(?:\.\d+)?) kg apples', sen)
Output:
['5.5']
['5']
? designates an optional segment of a regex.
re.findall(r'((\d+\.)?\d+)', sentence)
You can use number = re.findall(r'(\d+\.?\d*) kg apples', sentence)
You change your regex to match it:
(\d+(?:\.\d+)?)
\.\d+ matches a dot followed by at least one digit. I made it optional, because you still want one digit.
re.findall(r'[-+]?[0-9]*\.?[0-9]+.', sentence)
Non-regex solution
sentence = "I have 5.5 kg apples and 6 kg pears"
words = sentence.split(" ")
[words[idx-1] for idx, word in enumerate(words) if word == "kg"]
# => ['5.5', '6']
You can then check whether these are valid floats using
try:
float(element)
except ValueError:
print "Not a float"
The regex you need should look like this:
(\d+.?\d*) kg apples
You can do as follows:
number = re.findall(r'(\d+.?\d*) kg apples', sentence)
Here is an online example

Categories