-1

I have a list of elements ("tokens") that I assume are acting like strings. I want to find words with an underscore in them and replace the underscore with a space. I have the following code:

for e in tokens:
      if '_' in e:
            cmpd = list(e)
            cmpd[e.find('_')] = ' '
            ''.join(cmpd)
            new_tokens[index] = cmpd

It's basically identical to what's here: Change one character in a string in Python?

Later I'm trying to concatenate all the list elements in a sentence, each separated by a space, but I get the following error:

TypeError: can only concatenate list (not "str") to list

And if I print out e and cmpd, I get this output:

e: my_string

cmpd: ['m', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g']

Why is cmpd a list and not a string?

Community
  • 1
  • 1
eihe
  • 51
  • 6

5 Answers5

3

You need to assign ''.join(cmpd) to cmpd using =.:

cmpd=''.join(cmpd)
Trelzevir
  • 767
  • 6
  • 11
2
''.join(cmpd)

This line converts cmpd to a string, then throws that string away. You should keep the string:

cmpd = ''.join(cmpd)
kindall
  • 178,883
  • 35
  • 278
  • 309
2

There are a lot of problems here:

  • you use an index that is not defined,
  • .join does not work inplace;
  • if a token contains multiple underscores only one will be replaced;
  • if a token does not contain an underscore, it is not added; and
  • ...

What about:

new_tokens = [token.replace('_',' ') for token in tokens]

This replaces the entire loop and makes it very clear that you are replacing underscores with spaces.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • The replace function is good to know, thanks for that! I don't have any words with more than one underscore, so I wasn't too bothered with finding multiple underscores. In this case, I suppose I could write `cmpd = e.replace('_',' ')` which is certainly neater! The for loop is necessary though, as I have multiple clauses for different cases. – eihe Feb 08 '17 at 14:48
  • 1
    @eihe: yeah in case the loop is more complex, you can indeed write `cmpd = ...`. If it is however a simple problem list comprehension is the way to go since it is faster and more elegant. – Willem Van Onsem Feb 08 '17 at 14:51
1
no_underscores = [x.replace('_', ' ') for x in tokens]
print(' '.join(no_underscores))

So what happens is that you create a new list (you can also overwrite the previous one) that contains the elements of the old one but without the underscores (.replace works even if the string you are looking for is not there). On the second line all elements of the new list are joined together with a space in between them.

If you feel comfortable with the above, you can even combine them like so:

print(' '.join(x.replace('_', ' ') for x in tokens))

which has the advantage of not creating any extra lists.

Ma0
  • 15,057
  • 4
  • 35
  • 65
0

when you get to this line cmpd = list(e) e is a string and you are converting it to a list this will make each character an item in a list

davidejones
  • 1,869
  • 1
  • 16
  • 18