-2

Given the following string:

mystring = "today is a very boring day" 

And the list of words:

mylist1 = ["today", "is", "very boring", "today is a", "very boring day"]
mylist2 = ["today", "is", "today is a", "very boring" "very boring day"]
mylist3 = ["is", "a", "today is", "very boring", "very boring day"]

How can I create a function that helps me to .join() elements from any list in order to recreate mystring?

def string_from_list(mylist, mystring):
  return the_matching_string

matching_string1 = string_from_list(mylist1, mystring)
matching_string2 = string_from_list(mylist2, mystring)
matching_string3 = string_from_list(mylist3, mystring)

print(matching_string1)
# Today is a very boring day
print(matching_string2)
# Today is a very boring day
print(matching_string3)
# Today is a very boring day
  • What is the output of `string_form_list` if `mystring = "2022 is a very boring year" `? – Laci Feb 14 '22 at 19:13
  • How would this function know to not return `very boring day today is a`? What are the rules that you, as a human, would apply to this string to get back to the original sentence. – JNevill Feb 14 '22 at 19:14
  • @j1-lee it's the result of print(). The result would imply that `mystring = "Today is a very boring day"` and that `matching_string="Today is a very boring day"` – Federico Motta Feb 14 '22 at 19:14
  • @Laci that would return an `Error` – Federico Motta Feb 14 '22 at 19:16
  • Yes, but you CANNOT reconstruct the original string from the list of words. There is no combination that produces a match. You can produce a match with lower case `today`, but not the original. And indeed, what would be the point? If you're just returning the original string, what have you learned? – Tim Roberts Feb 14 '22 at 19:17
  • @JNevill prolly I'd start by doing a `mystring.split()` to create indexes and to have the possibility to order it logically – Federico Motta Feb 14 '22 at 19:21
  • 1
    @j1-lee I edited the question so it's more clear what I mean :) – Federico Motta Feb 14 '22 at 19:27
  • In `mylist3`, how would you be able to tell that `a` should come after `is` in the unscrambled string? – Samwise Feb 14 '22 at 20:09
  • Your logic works for the given mylist but can fail badly for other lists. Try eg ["A", 'safe',"life","is", "a", "life", "not worth living"]. How do you know which combination of elements of mylist to take – William Feb 14 '22 at 20:46

2 Answers2

3

The solution to your problem as stated is simply:

mystring = "Today is a very boring day"
mylist = ["Today", "is", "very boring", "today is a", "very boring day"]

def string_from_list(mylist, mystring):
    return mystring

matching_string = string_from_list(mylist, mystring)
print(mystring == matching_string)  # True

i.e. passing the original mystring argument to string_from_list makes the problem of returning a matching_string such that mystring == matching_string trivial -- just ignore mylist and return mystring.

The more interesting problem is reconstructing mystring given only mylist. This can be done by combining strings that are subsets of other strings, and joining what remains.

Since you need to combine strings case-insensitively (e.g. to combine Today with today is a), you can then loop back and use non-lowercase strings from the original list to "fix" the case-normalized combined string, yielding the original string.

def string_from_list(mylist: list[str]) -> str:
    # Reconstruct the string, normalized to lowercase.
    mystring = ' '.join(
        s for s in mylist if not any(
            s != t and s.lower() in t.lower() for t in mylist
        )
    )
    # Correct case using hints from original list.
    for s in mylist:
        mystring = mystring.replace(s.lower(), s)
    return mystring


mystring = "Today is a very boring day"
mylist = ["Today", "is", "very boring", "today is a", "very boring day"]

print(string_from_list(mylist))     # Today is a very boring day
matching_string = string_from_list(mylist)
print(mystring == matching_string)  # True
Samwise
  • 68,105
  • 3
  • 30
  • 44
  • @wooooooo if you have `mystring` passed in as a parameter, and the goal is to return a string that's equivalent to `mystring`, why would you bother with `mylist`? KISS. If you have a function that *only* has `mylist` as a parameter (which is not the way that OP framed the question), then the problem is more interesting -- you can't just `join` the strings together, you have to combine the overlapping ones first to avoid duplicating words. – Samwise Feb 14 '22 at 19:22
  • I finally understand the OP's question... – Laci Feb 14 '22 at 19:26
  • This doesn't work if you change the order of the words. I've edited my question to make it clearer – Federico Motta Feb 14 '22 at 19:39
  • There's no solution that can cope with the words being scrambled arbitrarily. – Samwise Feb 14 '22 at 20:08
  • @Samwise can you explain whats been done in `mystring.join()`.It would be better if you can explain by editing the answer. – Faraaz Kurawle Feb 15 '22 at 10:27
  • **combining strings that are subsets of other strings, and joining what remains** – Samwise Feb 15 '22 at 15:03
0
mylist0= ["A", 'safe',"life","is", "a", "life", "not worth living"]
mylist1 = ["today", "is", "very boring", "today is a", "very boring day"]
mylist2 = ["today", "is", "today is a", "very boring" "very boring day"]
mylist3 = ["is", "a", "today is", "very boring", "very boring day"]

By just seeing the above list, we know that after joining it using .join function, we will a grammatically incorrect sentence.

What we can do is:

  1. Using request module, to interact with grammar or sentence corrector API's from web and get the string.
  2. Use a module named language check in Python to check your sentence and correct it.

Some useful links:

Faraaz Kurawle
  • 1,085
  • 6
  • 24