我可以创建一个“视图"吗?在 Python 列表中? [英] Can I create a "view" on a Python list?

查看:48
本文介绍了我可以创建一个“视图"吗?在 Python 列表中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很大的列表l.我想创建一个从元素 4 到元素 6 的视图.我可以用序列切片来完成.

<预><代码>>>>l = 范围(10)>>>lv = l[3:6]>>>lv[3, 4, 5]

然而lvl 的一个副本.如果我更改基础列表,lv 不会反映更改.

<预><代码>>>>l[4] = -1>>>lv[3, 4, 5]

反之亦然 我希望对 lv 的修改也反映在 l 中.除此之外,列表大小不会改变.

我不期待建立一个大班来做到这一点.我只是希望其他 Python 大师可能知道一些隐藏的语言技巧.理想情况下,我希望它可以像 C 中的指针算法一样:

int lv[] = l + 3;

解决方案

Python 标准库中没有列表切片"类(也没有内置).因此,您确实需要一个类,尽管它不需要很大——尤其是如果您对只读"和紧凑"切片感到满意.例如:

导入集合类 ROListSlice(collections.Sequence):def __init__(self, alist, start, alen):self.alist = alistself.start = 开始self.alen = 艾伦def __len__(self):返回 self.alendef adj(self, i):如果 i<0: i += self.alen返回 i + self.startdef __getitem__(self, i):返回 self.alist[self.adj(i)]

这有一些限制(不支持切片"),但对于大多数用途来说可能没问题.

要使这个序列为 r/w,您需要添加 __setitem____delitem__insert:

class ListSlice(ROListSlice):def __setitem__(self, i, v):self.alist[self.adj(i)] = vdef __delitem__(self, i, v):del self.alist[self.adj(i)]self.alen -= 1定义插入(自我,我,V):self.alist.insert(self.adj(i), v)self.alen += 1

I have a large list l. I want to create a view from element 4 to 6. I can do it with sequence slice.

>>> l = range(10)
>>> lv = l[3:6]
>>> lv
[3, 4, 5]

However lv is a copy of a slice of l. If I change the underlying list, lv does not reflect the change.

>>> l[4] = -1
>>> lv
[3, 4, 5]

Vice versa I want modification on lv reflect in l as well. Other than that the list size are not going to be changed.

I'm not looking forward to build a big class to do this. I'm just hoping other Python gurus may know some hidden language trick. Ideally I hope it can be like pointer arithmetic in C:

int lv[] = l + 3;

解决方案

There is no "list slice" class in the Python standard library (nor is one built-in). So, you do need a class, though it need not be big -- especially if you're content with a "readonly" and "compact" slice. E.g.:

import collections

class ROListSlice(collections.Sequence):

    def __init__(self, alist, start, alen):
        self.alist = alist
        self.start = start
        self.alen = alen

    def __len__(self):
        return self.alen

    def adj(self, i):
        if i<0: i += self.alen
        return i + self.start

    def __getitem__(self, i):
        return self.alist[self.adj(i)]

This has some limitations (doesn't support "slicing a slice") but for most purposes might be OK.

To make this sequence r/w you need to add __setitem__, __delitem__, and insert:

class ListSlice(ROListSlice):

    def __setitem__(self, i, v):
        self.alist[self.adj(i)] = v

    def __delitem__(self, i, v):
        del self.alist[self.adj(i)]
        self.alen -= 1

    def insert(self, i, v):
        self.alist.insert(self.adj(i), v)
        self.alen += 1

这篇关于我可以创建一个“视图"吗?在 Python 列表中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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