pythonpython-3.xlistset

I have a set of words I would like to exclude, and I want to check if each new word entered is contained wholly within another. How would I do this?


So I am currently making a word game, and I want to have it so that the user cannot enter a word that is wholly contained within another word (e.g. 'set' in 'subset'), however my current code:

noWord = False
for _word in used_words:
    if set(word).issubset(set(_word)):
        noWord = True
if noWord == False:
    # Calculate score for the word

makes it so that it doesn't matter what order the letters are in (e.g. playing 'pitch' would prevent you from playing 'chip') which is a feature I do not want. How would I go about doing this efficiently.

I tried searching the _word variable as a list and checking if each set of letters from that list matches the word variable, but that was incredibly inefficient. e.g.

wordAsAList == list(_word)
# All words have to be 3 letters or more in my game
for v in range(len(wordAsAList) - 2):
    for i in range(len(wordAsAList)):
        if len(wordAsAList) - v - 3 >= i:
            if ("".join(wordAsAList[i:(len(wordAsAList) - v)])) == word:
                noWord = True

Beyond that I have little to no clue how to solve the problem / make the code above more efficient. (Also I know I shouldn't use range(len(list)), but I still do anyway)

Thanks in advance :)


Solution

  • That is what set does. set create a set (that is a collection without any order, whose purpose is to verify what belongs to it, what is included in it. Well, sets. Like in math).

    To build a set, you call set with another collection of things. Like S=set([3, 1, 2]) is the set containing numbers 1, 2 and 3. Then set([1,3]).issubset(S) is True, since set {1,3} is included in set {1,2,3}

    And when you call set with something that is not a collection, you get an error. set(1) raises an error.

    Now, here, you called set with a string. That you consider to be a "atomic" value. So, you may think that it should have raised an error. But a string is a collection: a collection of chars. So S=set("hello") is really the set containing {'h', 'e', 'l', 'o'} (in any order). And T=set("lol") is also a set, {'o','l'} (I show them in random orders, since, like in maths, there is no order).

    So T.issubset(S) is True here. Because all elements of T are also elements of S.

    Now, that was "why". As for "how" it is very simple:

    "set" in "subset"
    

    is True.

    And this time, in the sense you expect it to be: because string "set" is included in string "subset".

    To check if a word is part of any word of a list, you can

    L=["subset", "hello", "world"] # example list of words
    any("set" in x for x in L) # True, because "set" is substring of one of the words of L
    any("lol" in x for x in L) # False, because "lol" is substring of no word x of L