Reputation: 341
I have what might be a rudimentary question, but it has been causing me some difficulty and I thought someone might be able to help me out.
My issue is related to list comprehensions. I have data that looks like this and what I would like to do is convert columns 1,2,and 3 into integers.
['airport', '2007', '175702', '32788']
['airport', '2008', '173294', '31271']
['request', '2005', '646179', '81592']
['request', '2006', '677820', '86967']
['request', '2007', '697645', '92342']
['request', '2008', '795265', '125775']
['wandered', '2005', '83769', '32682']
['wandered', '2006', '87688', '34647']
['wandered', '2007', '108634', '40101']
['wandered', '2008', '171015', '64395']
I have tried code like the following:
test = [map(int,x) for x in raw_csv]
But when I run this and print the result I get an empty list. If someone knows how to do this I would really appreciate you showing me how. Thanks for your time.
Upvotes: 0
Views: 100
Reputation: 365925
If you specifically want "all columns but the first", it's hard to beat John Kiparsky's answer. And if you want "all columns that can be converted should be", m.wasowski's try_int
is clean and simple.
But if you want something more general, that can be later expanded to, say, columns 1, 2, 3, and 7:
int_columns = {1, 2, 3, 7}
test = [[int(x) if i in int_columns else x for i, x in enumerate(row)]
for row in raw_csv]
But I'd probably refactor it into a reusable function:
def map_some(func, iterable, columns):
return [func(x) if i in columns else x for i, x in enumerate(iterable)]
test = [map_some(int, row, int_columns) for row in raw_csv]
Upvotes: 1
Reputation: 19753
a simple approach:
l = [['airport', '2007', '175702', '32788'], ['airport', '2008', '173294', '31271'], ['request', '2005', '646179', '81592'], ['request', '2006', '677820', '86967'], ['request', '2007', '697645', '92342'], ['request', '2008', '795265', '125775'], ['wandered', '2005', '83769', '32682'], ['wandered', '2006', '87688', '34647'], ['wandered', '2007', '108634', '40101'], ['wandered', '2008', '171015', '64395']]
[ [x[0]]+map(int,x[1:]) for x in l ]
output:
[['airport', 2007, 175702, 32788], ['airport', 2008, 173294, 31271], ['request', 2005, 646179, 81592], ['request', 2006, 677820, 86967], ['request', 2007, 697645, 92342], ['request', 2008, 795265, 125775], ['wandered', 2005, 83769, 32682], ['wandered', 2006, 87688, 34647], ['wandered', 2007, 108634, 40101], ['wandered', 2008, 171015, 64395]]
Upvotes: -1
Reputation: 7753
If you know that the first column is going to be non-int and the following columns will be ints, and this is going to stay constant, it's as simple as
result = [line[:1] + map(int, line[1:]) for line in lines]
Assuming this structure, this is the simplest way I can think of to get what you're looking for.
Upvotes: 2
Reputation: 6386
I would write a simple generator:
def safe_ints(sequence):
for item in sequence
try:
yield int(item)
except ValueError:
yield item
test = [safe_ints(row) for row in rows]
EDIT: as OP wants, if conversion fails, item is returned as it was.
Or just simple function, that works on single token:
def try_int(val):
try:
return int(val)
except ValueError:
return val
test = [map(try_int, row) for row in rows]
Upvotes: 2
Reputation: 5588
I think your map syntax is a little off.
In [2]: stuff = [['airport', '2007', '175702', '32788'],
['airport', '2008', '173294', '31271'],
['request', '2005', '646179', '81592'],
['request', '2006', '677820', '86967'],
['request', '2007', '697645', '92342'],
['request', '2008', '795265', '125775'],
['wandered', '2005', '83769', '32682'],
['wandered', '2006', '87688', '34647'],
['wandered', '2007', '108634', '40101'],
['wandered', '2008', '171015', '64395'],]
In [4]: map(lambda x: [x[0], int(x[1]), int(x[2]), int(x[3])], stuff)
Out[4]:
[['airport', 2007, 175702, 32788],
['airport', 2008, 173294, 31271],
['request', 2005, 646179, 81592],
['request', 2006, 677820, 86967],
['request', 2007, 697645, 92342],
['request', 2008, 795265, 125775],
['wandered', 2005, 83769, 32682],
['wandered', 2006, 87688, 34647],
['wandered', 2007, 108634, 40101],
['wandered', 2008, 171015, 64395]]
Upvotes: 2