更新切片列表 [英] Updating a sliced list

查看:95
本文介绍了更新切片列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为我了解Python切片操作,但是当我尝试更新切片列表时,我感到困惑:

I thought I understood Python slicing operations, but when I tried to update a sliced list, I got confused:

>>> foo = [1, 2, 3, 4]
>>> foo[:1] = ['one'] # OK, foo updated
>>> foo
['one', 2, 3, 4] 
>>> foo[:][1] = 'two' # why foo not updated?
>>> foo
['one', 2, 3, 4] 
>>> foo[:][2:] = ['three', 'four'] # Again, foo not updated
>>> foo
['one', 2, 3, 4] 

为什么foo[:][1] = 'two'之后不更新foo?

Why isn't foo updated after foo[:][1] = 'two'?

更新:也许我没有清楚地解释我的问题.我知道切片时会创建一个新列表.我的疑问是为什么切片任务会更新列表(例如foo[:1] = ['one']),但是如果切片有两个级别,它就不会更新原始列表(例如foo[:][2:] = ['three', 'four']).

Update: Maybe I didn't explain my questions clearly. I know when slicing, a new list is created. My doubt is why a slicing assignment updates the list (e.g. foo[:1] = ['one']), but if there are two levels of slicing, it doesn't update the original list (e.g. foo[:][2:] = ['three', 'four']).

推荐答案

这是因为python 具有可以分配的 l 值.相反,某些表达式具有不同的赋值形式.

This is because python does not have l-values that could be assigned. Instead, some expressions have an assignment form, which is different.

A foo[something]是用于以下方面的语法糖:

A foo[something] is a syntactic sugar for:

foo.__getitem__(something)

,但是foo[something] = bar是一种语法糖,因为它与众不同:

but a foo[something] = bar is a syntactic sugar for rather different:

foo.__setitem__(something, bar)

切片只是something的特例,因此foo[x:y]扩展为

Where a slice is just a special case of something, so that foo[x:y] expands to

foo.__getitem__(slice(x, y, None))

foo[x:y] = bar扩展为

foo.__setitem__(slice(x, y, None), bar)

现在带有切片的__getitem__返回一个新列表,该列表是指定范围的副本,因此对其进行修改不会影响原始数组.借助__setitem__是另一种方法来分配作品,可以简单地完成其他事情.

Now a __getitem__ with slice returns a new list that is a copy of the specified range, so modifying it does not affect the original array. And assigning works by the virtue of __setitem__ being a different method, that can simply do something else.

但是,特殊分配处理仅适用于最外部的操作.成分是正则表达式.所以当你写

However the special assignment treatment applies only to the outermost operation. The constituents are normal expressions. So when you write

foo[:][1] = 'two'

它扩展到

foo.__getitem__(slice(None, None, None)).__setitem__(1, 'two')

foo.__getitem__(slice(None, None, None))部分创建一个副本,并且该副本被__setitem__修改.但不是原始数组.

the foo.__getitem__(slice(None, None, None)) part creates a copy and that copy is modified by the __setitem__. But not the original array.

这篇关于更新切片列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆