就地修改嵌套列表元素的最优雅的方法
我有一个看起来像这样的二维列表:
table = [['donkey', '2', '1', '0'], ['goat', '5', '3', '2']]
我想将最后三个元素更改为整数,但下面的代码感觉非常丑陋:
for row in table:
for i in range(len(row)-1):
row[i+1] = int(row[i+1])
但我宁愿有看起来像这样的东西:
for row in table:
for col in row[1:]:
col = int(col)
我认为应该有一种方法来编写上面的代码,但是切片创建了一个与原始列表分开的迭代器/新列表,因此引用不会保留。
有什么方法可以得到更Pythonic的解决方案吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
上面看起来是不是更Pythonic?
Does above look more pythonic?
尝试:
据我所知,分配给
list
切片会强制操作就地完成,而不是创建新的list
。Try:
AFAIK, assigning to a
list
slice forces the operation to be done in place instead of creating a newlist
.我非常喜欢谢卡尔的回答。
作为一般规则,在编写 Python 代码时,如果您发现自己在 range(len(somelist)) 中编写了 f
或 i
,那么您就做错了:enumerate
如果您有一个列表,zip
或itertools.izip
如果您有 2 个或更多要并行迭代的列表在您的情况下,第一列是不同的,所以你不能优雅地使用枚举:
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:
您的“丑陋”代码可以通过使用两个参数调用
range
来改进:如果您坚持在适当的位置更改项目而不分配新的临时列表(或者通过使用列表理解、
map
和/或切片)。请参阅 是否有相当于“map”的就地 虽然我不推荐这样做,但您也可以通过引入自己的就地映射函数来使此代码更通用:
就我个人而言,我发现这更少Pythonic。最好只有一种明显的方法可以做到这一点,但这不是。
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.
使用列表理解:
Use list comprehensions:
这将起作用:
但是您可能需要考虑在首次创建列表时进行转换。
This will work:
However you might want to think about doing the conversion at the point where the list is first created.
这实现了您正在寻找的内容。这是一个可读的解决方案。您也可以使用 listcomp 来获得类似的结果。
This accomplishes what you are looking for. It is a readable solution. You can go for similar one using listcomp too.