Kelvin Davis Kelvin Davis - 24 days ago 10
Python Question

Comparing tuples to a list of non-tuples

Wrote the code below to take in a list/set and a string and if I am able to break the string into two words that are in the list then I return. I know I'm close, I just cant get the comparison right or something.

e.g.

wordBreakEasy("snowfall", ("apple", "fall", ..., "snow"))


would return
True
.

def wordBreakEasy(str1, wordset):
wordset1 = set(wordset)
breakup = ['%s %s' % (str1[:i], str1[i:]) for i in range(1, len(str1))]
newlist = []
for x in breakup:
newlist.append((x.split()))
wordset2 = set(map(tuple, newlist))

for wordset2 in wordset1:


This is where I don't know where to go now.

Answer

Add your word pairs as tuples, rather than as a space-delimited single string, then filter that list on tuples that are a subset of your wordset1 set:

breakup = [(str1[:i], str1[i:]) for i in range(1, len(str1))]
present = [tup for tup in breakup if not wordset1.issuperset(tup)]

I used the set.issuperset() method here; it returns True if all of the elements in the argument iterable are present in the set, so if it returns True only if both elements in the tuple are present.

Only then combine the words into a single string:

newlist = [' '.join(tup) for tup in present]

You don't need those intermediary lists, really; you only need to find if there is any such tuple that is a subset for your function to return True:

breakup = ((str1[:i], str1[i:]) for i in range(1, len(str1)))
return any(wordset1.issuperset(tup) for tup in breakup)

I turned breakup into a generator expression; no need for the whole list to be built if you can find a matching word-pair early on. The any() function returns True as soon as one of the values it iterates over is true. Since that's a generator expression too, this tests word pairs lazily until a match is found.

Demo:

>>> def wordBreakEasy(str1, wordset):
...     wordset1 = set(wordset)
...     breakup = ((str1[:i], str1[i:]) for i in range(1, len(str1)))
...     return any(wordset1.issuperset(tup) for tup in breakup)
...
>>> wordBreakEasy("snowfall", ("apple", "fall", "...", "snow"))
True
>>> wordBreakEasy("snowflake", ("apple", "fall", "...", "snow"))
False