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'?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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...
Method 2
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()andfilter()return iterators. If you really need alist, 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 regularforloop
(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
Method 3
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!
Method 4
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]
Method 5
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']
Method 6
from this link:
you can use rstrip() method. Example
mystring = "hellon"
print(mystring.rstrip('n'))
Method 7
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.
Method 8
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')]
Method 9
This will also work,
f=open('in.txt','r')
for line in f:
parline = line[:-1].split(',')
Method 10
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
Method 11
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.
Method 12
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).
Method 13
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])
Method 14
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)
....
Method 15
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 ''
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0