Lola
Lola

Reputation: 97

map function in Python

Content of file scores.txt that lists the performance of players at a certain game:

80,55,16,26,37,62,49,13,28,56
43,45,47,63,43,65,10,52,30,18
63,71,69,24,54,29,79,83,38,56
46,42,39,14,47,40,72,43,57,47
61,49,65,31,79,62,9,90,65,44
10,28,16,6,61,72,78,55,54,48

The following program reads the file and stores the scores into a list

f = open('scores.txt','r')
L = []
for line in f:
    L = L + map(float,str.split(line[:-1],','))
print(L)

But it leads to error messages. I was given code in class so quite confused as very new to Pyton. Can I fix code?

Upvotes: 0

Views: 2383

Answers (1)

cs95
cs95

Reputation: 402483

It appears you've adapted python2.x code to use in python3.x. Note that map does not return a list in python3.x, it returns a generator map object (not a list, basically) that you've to convert to a list appropriately.

Furthermore, I'd recommend using list.extend instead of adding the two together. Why? The former creates a new list object every time you perform addition, and is wasteful in terms of time and space.

numbers = []
for line in f:
    numbers.extend(list(map(float, line.rstrip().split(','))))

print(numbers)

An alternative way of doing this would be:

for line in f:
    numbers.extend([float(x) for x in line.rstrip().split(',')]) 

Which happens to be slightly more readable. You could also choose to get rid of the outer for loop using a nested list comprehension.

numbers = [float(x) for line in f for x in line.rstrip().split(',')]

Also, forgot to mention this (thanks to chris in the comments), but you really should be using a context manager to handle file I/O.

with open('scores.txt', 'r') as f:
    ...

It's cleaner, because it closes your files automatically when you're done with them.


After seeing your ValueError message, it's clear there's issues with your data (invalid characters, etc). Let's try something a little more aggressive.

numbers = []
with open('scores.txt', 'r') as f:
    for line in f:
        for x in line.strip().split(','):
            try:
                numbers.append(float(x.strip()))
            except ValueError:
                pass

If even that doesn't work, perhaps, something even more aggressive with regex might do it:

import re

numbers = []
with open('scores.txt', 'r') as f:
    for line in f:
        line = re.sub('[^\d\s,.+-]', '', line)
        ... # the rest remains the same

Upvotes: 7

Related Questions