How to remove n from a list element?

Question:

I’m trying to get Python to a read line from a .txt file and write the elements of the first line into a list. The elements in the file were tab- separated so I used split("t") to separate the elements. Because the .txt file has a lot of elements I saved the data found in each line into a separate list.

The problem I currently have is that it’s showing each list like this:

['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']

How can I remove n from the last element of the list and make it just '7.3'?

Asked By: Mr Wotan

||

Answers:

If you want to remove n from the last element only, use this:

t[-1] = t[-1].strip()

If you want to remove n from all the elements, use this:

t = map(lambda s: s.strip(), t)

You might also consider removing n before splitting the line:

line = line.strip()
# split line...
Answered By: Bolo

You access the last element of the set and then store the value in a variable.

So you have:

fileName = '7.3n'

then just do:

fileName.strip()

which will leave you with 7.3. Then store that value back in the last element of the set.

You can use lstrip() or rstrip() to remove just the left or right side.

Answered By: Pavan

As an alternate method, if you know that there are no spaces in your data, which it seems is the case, you can use split() (with no arguments). This splits on white space and uses a more efficient algorithm than the other version of split. It also strips whitespace from both ends.

line = line.split()

And that’s it.

Answered By: JoshD

Using list comprehension:

myList = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']

[(el.strip()) for el in myList]
Answered By: rogeriopvl

You could do –

DELIMITER = 't'
lines = list()
for line in open('file.txt'):
    lines.append(line.strip().split(DELIMITER))

The lines has got all the contents of your file.

One could also use list comprehensions to make this more compact.

lines = [ line.strip().split(DELIMITER) for line in open('file.txt')]
Answered By: Srikar Appalaraju

str.strip() removes the whitespace characters. you can also pass custom characters as argument to strip. The strip function removes the whitespace/custom characters on both ends of the string. lstrip() and rstrip() are left strip and right strip functions resp.

Eg:

test_str = "Vishakan" 
test_str = test_str.strip()

test_str’s now Vishaka

Answered By: gopalkoduri

It sounds like you want something like the Perl chomp() function.

That’s trivial to do in Python:

def chomp(s):
    return s[:-1] if s.endswith('n') else s

… assuming you’re using Python 2.6 or later. Otherwise just use the slightly
more verbose:

def chomp(s):
    if s.endwith('n'):
        return s[:-1]
    else:
        return s

If you want to remove all new lines from the end of a string (in the odd case where one might have multiple trailing newlines for some reason):

def chomps(s):
    return s.rstrip('n')

Obviously you should never see such a string returned by any normal Python file object’s readline() nor readlines() methods.

I’ve seen people blindly remove the last characters (using s[:-1] slicing) from the results of file readline() and similar functions. This is a bad idea because it can lead to an error on the last line of the file (in the case where a file ends with anything other than a newline).

At first you might be lulled into a false sense of security when blindly stripping final characters off lines you’ve read. If you use a normal text editor to create your test suite files you’ll have a newline silently added to the end of the last line by most of them. To create a valid test file use code something like:

f = open('sometest.txt', 'w')
f.write('some text')
f.close()

… and then if you re-open that file and use the readline() or readlines() file methods on it you’ll find that the text is read without the trailing newline.

This failure to account for text files ending in non-newline characters has plagued many UNIX utilities and scripting languages for many years. It’s a stupid corner base bug that creeps into code just often enough to be a pest but not often enough for people to learn from it. We could argue that “text” files without the ultimate newline are “corrupt” or non-standard; and that may be valid for some programming specifications.

However, it’s all too easy to ignore corner cases in our coding and have that ignorance bite people who are depending on your code later. As my wife says: when it comes to programming … practice safe hex!

Answered By: Jim Dennis

This will also work,

f=open('in.txt','r')

    for line in f:
            parline = line[:-1].split(',')
Answered By: drunkbn

from this link:

you can use rstrip() method. Example

mystring = "hellon"    
print(mystring.rstrip('n'))
Answered By: itagomo

This works to take out the n (new line) off a item in a list
it just takes the first item in string off

def remove_end(s):
    templist=[]
    for i in s:
        templist.append(i)
    return(templist[0])
Answered By: sryzr

From Python3 onwards

map no longer returns a list but a mapObject, thus the answer will look something like

>>> map(lambda x:x.strip(),l)
<map object at 0x7f00b1839fd0>

You can read more about it on What’s New In Python 3.0.

map() and filter() return iterators. If you really need a list, a quick fix is e.g. list(map(...))

So now what are the ways of getting trough this?


Case 1 – The list call over map with a lambda

map returns an iterator. list is a function that can convert an iterator to a list. Hence you will need to wrap a list call around map. So the answer now becomes,

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']
>>> list(map(lambda x:x.strip(),l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

Very good, we get the output. Now we check the amount of time it takes for this piece of code to execute.

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n'];list(map(lambda x:x.strip(),l))"
100000 loops, best of 3: 2.22 usec per loop

2.22 microseconds. That is not so bad. But are there more efficient ways?


Case 2 – The list call over map withOUT a lambda

lambda is frowned upon by many in the Python community (including Guido). Apart from that it will greatly reduce the speed of the program. Hence we need to avoid that as much as possible. The toplevel function str.strip. Comes to our aid here.

The map can be re-written without using lambda using str.strip as

>>> list(map(str.strip,l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

And now for the times.

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n'];list(map(str.strip,l))"
1000000 loops, best of 3: 1.38 usec per loop

Fantastic. You can see the efficiency differences between the two ways. It is nearly 60% faster. Thus the approach without using a lambda is a better choice here.


Case 3 – Following Guidelines, The Regular way

Another important point from What’s New In Python 3.0 is that it advices us to avoid map where possible.

Particularly tricky is map() invoked for the side effects of the
function; the correct transformation is to use a regular for loop
(since creating a list would just be wasteful).

So we can solve this problem without a map by using a regular for loop.

The trivial way of solving (the brute-force) would be:-

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']
>>> final_list = []
>>> for i in l:
...     final_list.append(i.strip())
... 
>>> final_list
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

The timing setup

def f():
    l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']
    final_list = []
    for i in l:
         final_list.append(i.strip())
import timeit
print(min(timeit.repeat("f()","from __main__ import f")))

And the result.

1.5322505849981098

As you can see the brute-force is a bit slower here. But it is definitely more readable to a common programmer than a map clause.


Case 4 – List Comprehensions

A list comprehension here is also possible and is the same as in Python2.

>>> [i.strip() for i in l]
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

Now for the timings:

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n'];[i.strip() for i in l]"
1000000 loops, best of 3: 1.28 usec per loop

As you can see the list-comprehension is more effective than map (even that without a lambda). Hence the thumb rule in Python3 is to use a list comprehension instead of map


Case 5 – In-Place mechanisms and Space Efficiency (T-M-T)

A final way is to make the changes in-place within the list itself. This will save a lot of memory space. This can be done using enumerate.

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']
>>> for i,s in enumerate(l):
...     l[i] = s.strip()
... 
>>> l
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

The timing result would be 1.4806894720022683. But however this way is space effective.


Conclusion

A comparitive list of timings (Both Python 3.4.3 and Python 3.5.0)

----------------------------------------------------
|Case| method          | Py3.4 |Place| Py3.5 |Place|
|----|-----------------|-------|-----|-------|-----|
| 1  | map with lambda | 2.22u | 5   | 2.85u | 5   |
| 2  | map w/o lambda  | 1.38u | 2   | 2.00u | 2   |
| 3  | brute-force     | 1.53u | 4   | 2.22u | 4   |
| 4  | list comp       | 1.28u | 1   | 1.25u | 1   |
| 5  | in-place        | 1.48u | 3   | 2.14u | 3   |
----------------------------------------------------

Finally note that the list-comprehension is the best way and the map using lambda is the worst. But again — ONLY IN PYTHON3

Answered By: Bhargav Rao

I had this issue and solved it using the chomp function described above:

def chomp(s):
    return s[:-1] if s.endswith('n') else s

def trim_newlines(slist):
    for i in range(len(slist)):
        slist[i] = chomp(slist[i])
    return slist
.....
names = theFile.readlines()
names = trim_newlines(names)
....
Answered By: catchpolej

To handle many newline delimiters, including character combinations like rn, use splitlines.
Combine join and splitlines to remove/replace all newlines from a string s:

''.join(s.splitlines())

To remove exactly one trailing newline, pass True as the keepends argument to retain the delimiters, removing only the delimiters on the last line:

def chomp(s):
    if len(s):
        lines = s.splitlines(True)
        last = lines.pop()
        return ''.join(lines + last.splitlines())
    else:
        return ''
Answered By: teichert

Since the OP’s question is about stripping the newline character from the last element, I would reset it with the_list[-1].rstrip():

>>> the_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']
>>> the_list[-1] = ls[-1].rstrip()
>>> the_list
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

It’s O(1).

Answered By: srikavineehari
new_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3n']
for i in range(len(new_list)):
    new_list[i]=new_list[i].replace('n','')
print(new_list)

Output Will be like this

['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Answered By: Tanmoy Datta
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.