4

Okay, so I am having a problem swapping part of a string with part of another string in a list. I've seen the other similar questions on this site but none of them seem to work for me.

Let's say I have a list:

sentList = ['i like math', 'i am a cs expert']

Now I want to switch 'math' with 'cs' using variables determined by user input.

currentWord = input('Swap word: ')
newWord = input('with word: ')

So, now how would I swap the two so that my list would return the following:

sentList = ['i like cs', 'i am a math expert']

As always, thank you for any help. I think I can use the replace function but am not sure how. I imagine it would look something like this:

sentList = [sentListN.replace(currentWord, newWord) for sentListN in sentList]

But, obviously that does not work.

1
  • 1
    Lot of ambiguity in the question. Many scenarios possible here, like the one @Delgan mentioned. Commented Sep 26, 2017 at 7:27

6 Answers 6

1

A single liner using list comprehension.

[sent.replace(currentWord,newWord) if sent.find(currentWord)>=0 else sent.replace(newWord,currentWord) for sent in sentList]

So,

IN: sentList = ['i like math', 'i am a cs expert']
IN : currentWord = "math"
IN : newWord = "cs"
OUT : ['i like cs', 'i am a math expert']

Here, if sent.find('math')>=0 will find out if the string conntains 'math' , and if so, replaces it with 'cs', else it replaces 'cs' with 'math'. In case the string contains neither, then too it will print the original, as replace only works if the substring is found.


Edit : as @Rawing pointed out, there were a few bugs in the above code. So here is the new code that will handle every and all cases.

I have used re.sub to handle replacement of only words, and the replacement algorithm is that of how you would swap two variables, say for x and y, where we introduce a temporary variable t to help with the swap: t = x; x = y; y = t. This approach was chosen since we have to do Multiple substitution at the same time.

from re import sub

for s in sentList:

  #replace 'math' with '%math_temp%' in s (here '%math_temp%' is a dummy placeholder that we need to later substitute with 'cs')
  temp1 = sub(r'\bmath\b','%math_temp%' , s)

  #replace 'cs' with 'math' in temp1
  temp2 = sub(r'\bcs\b','math', temp1)

  #replace '%math_temp%' with 'cs' in temp2
  s = sub('%math_temp%','cs', temp2)

  print(s)

So this time on a bigger test case, we get :

IN : sentList = ['i like math', 'i am a cs expert', 'math cs', 'mathematics']
IN : currentWord = "math"
IN : newWord = "cs"

OUT : i like cs
      i am a math expert
      cs math
      mathematics
Sign up to request clarification or add additional context in comments.

6 Comments

Note that this will turn "math cs" into "cs cs". It'll also turn "mathematics" into "csematics".
@DakotaBrown, there is a slight logical error as Rawing pointed out. For simple use this is fine, but for complicated situations this fails.
I am working up a better logic. Will update again in a few @DakotaBrown
I see, please let me know when you do.
@DakotaBrown , check out the new and improved version :D
|
1

You can achieve it by simple swap function. Don't need to complicate code :)

def swap(str, x, y):
    words = []
    for w in str.split():
        if w == x:
            words.append(y)
        elif w == y:
            words.append(x)
        else:
            words.append(w)
    return ' '.join(words)

if __name__ == '__main__':
    sentList = ['i like math', 'i am a cs expert']
    word1 = 'math'
    word2 = 'cs'
    new_list = [swap(x, word1, word2) for x in sentList]
    print(new_list)

1 Comment

This was actually really useful in terms of learning, but I am not allowed to use a function for this.
1

The following code works. I used word1 (currentWord) and word2 (newWord) variables as user input

sentList = ['i like math', 'i am a cs expert']

word1 = 'math'
word2 = 'cs'

assert word1, word2 in sentList
sentList = [s.replace(word1, word2) if word1 in s
           else s.replace(word2, word1) if word2 in s
           else s for s in sentList]

If we break it down to steps, it looks like

for i, s in enumerate(sentList):
    if word1 in s:
        sentList[i] = s.replace(word1, word2)
    elif word2 in s:
        sentList[i] = s.replace(word2, word1)

2 Comments

This'll turn "math cs" into "cs cs" and "mathematics" into "csematics".
I ended up using another one, but this worked. Thank you, I appreciate the help!
0

You can try like this,

In [20]: currentWord = 'cs'

In [21]: newWord = 'math'

In [22]: [i.replace(currentWord,newWord) if  currentWord in i else i.replace(newWord,currentWord) if newWord in i else i for i in sentList]
Out[22]: ['i like cs', 'i am a math expert']

It's a simple combination of list comprehension and if else conditions.

Comments

0

This is a naive answer (words can be substrings of other words, etc), but following your approach, we can swap wa with wb by

wa=input....
wb=input....
new = [s.replace(wa,"_").replace(wb,wa).replace("_",wb) for s in sentList]

this way a sentence with both is transformed the following way:

"cs is older then math" --> "_ is older then math" --> "_ is older then cs" --> "math is older then cs"

1 Comment

Can you elaborate on the s.replace chaining? How does this work?
0

Assuming that each sentence only contains one word (a sentence can't contain both math and cs) just make a new list and append new strings to it:

newSentList = []
for sent in sentList:
    assert(currentWord in sent != newWord in sent)
    if currentWord in sent:
        newSentList.append(sent.replace(currentWord, newWord))
    else:
        newSentList.append(sent.replace(newWord, currentWord))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.