0

If I have a list of strings and want to eliminate leading and trailing whitespaces from it, how can I use .strip() effectively to accomplish this?

Here is my code (python 2.7):

for item in myList:
    item = item.strip()
    print item

for item in myList:
    print item

The changes don't preserve from one iteration to the next. I tried using map as suggested here (https://stackoverflow.com/a/7984192) but it did not work for me. Please help.

Note, this question is useful:

  1. An answer does not exist already
  2. It covers a mistake someone new to programming / python might make
  3. Its title covers search cases both general (how to update values in a list) and specific (how to do this with .strip()).
  4. It addresses previous work, in particular the map solution, which would not work for me.
Community
  • 1
  • 1
phoenixdown
  • 828
  • 1
  • 10
  • 16

2 Answers2

3

I'm guessing you tried:

map(str.strip, myList)

That creates a new list and returns it, leaving the original list unchanged. If you want to interact with the new list, you need to assign it to something. You could overwrite the old value if you want.

myList = map(str.strip, myList)

You could also use a list comprehension:

myList = [item.strip() for item in myList]

Which many consider a more "pythonic" style, compared to map.

Kevin
  • 74,910
  • 12
  • 133
  • 166
  • Thanks - I didn't realize map returned a copy, and so failed to assign it anywhere! I think I made the same mistake trying the list comprehension method. Please let me know any errors in the answer I submitted below as well - currently I prefer it because it attempts to explain the error the code in the original question makes. Feel free to put the explanation in your own answer and I can approve it, barring someone else coming in with a more complete explanation. – phoenixdown Jun 10 '16 at 17:10
2

I'm answering my own question here in the hopes that it saves someone from the couple hours of searching and experimentation it took me.

As it turns out the solution is fairly simple:

index = 0
for item in myList:
    myList[index] = item.strip()
    index += 1

for item in myList:
    print "'"+item+"'"

Single quotes are concatenated at the beginning/end of each list item to aid detection of trailing/leading whitespace in the terminal. As you can see, the strings will now be properly stripped.

To update the values in the list we need to actually access the element in the list via its index and commit that change. I suspect the reason is because we are passing by value (passing a copy of the value into item) instead of passing by reference (directly accessing the underlying list[item]) when we declare the variable "item," whose scope is local to the for loop.

phoenixdown
  • 828
  • 1
  • 10
  • 16
  • 1
    A better solution to `index = 0 ... index += 1` is to use `for index, item in enumerate(myList):`. See [enumerate](https://docs.python.org/2/library/functions.html#enumerate). – SethMMorton Jun 10 '16 at 17:11
  • 1
    This solution should work just fine, although it's usually preferable to avoid incrementing indexes manually if at all possible. Also, when I want to check whether my strings have trailing/leading whitespace, I like to do `print repr(item)`. Saves me the trouble of concatenating quote marks myself. – Kevin Jun 10 '16 at 17:16
  • 1
    The problem of `item = item.strip()` having no effect on `myList` doesn't exactly have anything to do with pass-by-reference or pass-by-value. Essentially, assignment in Python causes the name to point to a new position in memory, leaving the value in the old memory unchanged. For example, In the first loop of `for item in myList:`, maybe `myList[0]` points to 0x1234, and `item` points to `0x1234`. Doing `item = item.strip()` will cause a new string to be allocated at 0x5678, and `item` will point at that new string. Meanwhile, `myList[0]` still happily points to `0x1234`. – Kevin Jun 10 '16 at 17:23
  • oh man that's subtle, feel free to add that explanation to your answer and i can approve it, thanks for the knowledge – phoenixdown Jun 10 '16 at 17:33