I have a 2D list that looks like this:
table = [['donkey', '2', '1', '0'], ['goat', '5', '3', '2']]
I want to change the last three elements to integers, but the code below feels very ugly:
for row in table:
for i in range(len(row)-1):
row[i+1] = int(row[i+1])
But I'd rather have something that looks like:
for row in table:
for col in row[1:]:
col = int(col)
I think there should be a way to write the code above, but the slice creates an iterator/new list that's separate from the original, so the references don't carry over.
Is there some way to get a more Pythonic solution?
Use list comprehensions:
Does above look more pythonic?
Try:
AFAIK, assigning to a
list
slice forces the operation to be done in place instead of creating a newlist
.I like Shekhar answer a lot.
As a general rule, when writing Python code, if you find yourself writing f
or i in range(len(somelist))
, you're doing it wrong:enumerate
if you have a single listzip
oritertools.izip
if you have 2 or more lists you want to iterate on in parallelIn your case, the first column is different so you cannot elegantly use enumerate:
Your "ugly" code can be improved just by calling
range
with two arguments:This is probably the best you can do if you insist on changing the items in place without allocating new temporary lists (either by using a list comprehension,
map
, and/or slicing). See Is there an in-place equivalent to 'map' in python?Although I don't recommend it, you can also make this code more general by introducing your own in-place map function:
Personally, I find this less Pythonic. There is preferably only one obvious way to do it, and this isn't it.
This accomplishes what you are looking for. It is a readable solution. You can go for similar one using listcomp too.