2

I have a list file made up of car details.

e.g.

1000001 Volvo v8
1000002 Mazda 2.0

5 Answers5

5

It sounds like you need to split each line; you can use a list comprehension, as follows

cars = [line.split() for line in open("Cars.txt")]

As mentioned in the comments; you want numerical representations of the numbers. To do this you need to convert the numerical columns into numbers. E.g.

for i in range(len(cars)):
    cars[i][0] = int(cars[i][0])
    cars[i][-1] = int(cars[i][-1])

Then e.g. cars[0][0] will be a number. Alternatively, if the numbers will always be positive integers, you can condense this to:

readline = lambda l: [int(n) if n.isdigit() else n for n in l.split()]
cars = [[ readline(line) for line in open("Cars.txt")]

For any more complicated datafile reading, you might want to use e.g. pandas.

Generators

As pointed out by zondo in the comments, you might consider using a generator instead, which doesn't load all the data into memory (instead "generating" each element when requested); this can be done by swapping [] for () in the comprehension:

cars = (line.split() for line in open("Cars.txt"))

Then you can still iterate over cars as you would a list, but you can't index into a generator, as you can a list.

jmetz
  • 12,144
  • 3
  • 30
  • 41
  • As a note, you might want to use `()` instead of `[]` to save memory. Of course, that won't necessarily work in all cases, but it can be advantageous. – zondo Mar 18 '16 at 13:30
  • @zondo: In this case the OP implied that they wanted a list at the end, (not a generator) - but a good comment in general. – jmetz Mar 18 '16 at 13:31
  • I realize that he did say that, but he might not know about generators, so wouldn't know that they could be more efficient. – zondo Mar 18 '16 at 13:33
  • This is a method I've used. If I return the firs item i.e cars[0] it returns 1000001 Volvo 34000, I now need to able to access the 34000 and multiply it by a number and store/output that number – bobby zamora Mar 18 '16 at 13:41
  • The index `-1` is used to access the end of a list, tuple, etc. – jmetz Mar 19 '16 at 18:29
  • Did not know that, amazing :) – bobby zamora Mar 21 '16 at 12:11
2

If you want a proper way to access all the information in the text file, you can simply define a class for it. And later fill it with information from the file. Here is an example implementation. I used unpack operator (*) here.

class Car(object):

    def __init__(self, id, name, price):
        self.id = id
        self.name = name
        self.price = price

    def __str__(self):
        return self.id + ' ' + self.name + ' ' + self.price


file = open("file.txt", 'r')
cars = [Car(*line.split()) for line in file]

for c in cars:
    print c

Or use generator expression if you have a really large file

cars = (Car(*line.split()) for line in file)

In both cases it prints,

1000001 Volvo 34000
1000002 Mazda 23000
Community
  • 1
  • 1
Hossain Muctadir
  • 3,546
  • 1
  • 19
  • 33
0

This is how you can store your results in a list, using the split function:

cars = []

with open("cars.txt", 'r') as f:
    for line in f:
        cars.append(line.split())

If you want to be able to search quickly based on your unique ID, you might be better off using a dictionary.

Pep_8_Guardiola
  • 5,002
  • 1
  • 24
  • 35
  • This is the method I've used, and its fine, but I need to be able to actually get at the cost of each car and multiply it by a number. That's my mains struggle, I can't seem to actually get hold of that value. – bobby zamora Mar 18 '16 at 13:39
0

Here is a pure python way:

text = '1000001 Volvo 34000 1000002 Mazda 23000'

# Split text into one list
l = text.split()

# Split list into list of list every 3rd element
l = [l[i:i+3] for i in range(0, len(l), 3)]
print l

[['1000001', 'Volvo', '34000'], ['1000002', 'Mazda', '23000']]
tmthydvnprt
  • 10,398
  • 8
  • 52
  • 72
  • FYI, originally the text was all on one line... if this is not the case after the question update, then this answer is not really correct... – tmthydvnprt Mar 18 '16 at 13:42
-1

This could be done with a regex to produce a list of tuples:

import re

text = '1000001 Volvo 34000 1000002 Mazda 23000'

l = re.findall(r'(\d+) (\w+) (\d+)', text)
print l

[('1000001', 'Volvo', '34000'), ('1000002', 'Mazda', '23000')]

If you really need a list of lists you can convert it:

l = [list(x) for x in l]
print l

[['1000001', 'Volvo', '34000'], ['1000002', 'Mazda', '23000']]
tmthydvnprt
  • 10,398
  • 8
  • 52
  • 72
  • Why use regex instead of a simple split? Since `.split()` is built into the Python language, can't we assume that it uses the most efficient approach? – zondo Mar 18 '16 at 13:32
  • Well it is one way to do it... you are correct `regex` is typically a performance hit... see my new [answer](http://stackoverflow.com/a/36085911/2087463) for a pure python way to do it. – tmthydvnprt Mar 18 '16 at 13:39
  • Regex is an advanced technique. This OP is obviously not advanced at python, so I downvoted. – joel goldstick Mar 18 '16 at 13:40
  • Why not? He is asking for something that can be done simply. Why introduce a more advanced approach that performs worse? – zondo Mar 18 '16 at 13:42
  • That is how one learns... they don't have to use it. **I have learned about many new techniques thru someone's SO answers/comments that didn't help me at the moment but that I went to research later.** It can be tucked away in the brain for when the input gets more complex and you *really* need a `regex` parser. – tmthydvnprt Mar 18 '16 at 13:44
  • FYI, originally the text was all on one line... if this is not the case after the question update, then this answer is not really correct... – tmthydvnprt Mar 18 '16 at 13:47
  • @joelgoldstick I would petition you to remove the downvote because of my comment above. Questions and Answers are not just for the OP, *they are for posterity as well*! Especially if you think the OP is not advanced, I would argue that then you should want to expose them to small reproducible chunks of more advanced topics. This keeps them curious and adds a little direction for self discovery. At least for my self, SO has been a pedagogical tool that is much more influential than getting the answer to one specific question. – tmthydvnprt Mar 18 '16 at 14:04
  • 1
    I found it all very useful thank you, but at this very moment the simplest approach is always the best, and thanks to all of you I have advanced tremendously. – bobby zamora Mar 21 '16 at 12:12