Python 使用就地切片扩展列表类

Python 使用就地切片扩展列表类,python,list,class,inheritance,Python,List,Class,Inheritance,我试图编写一个从Pythonlist类继承的类,并且有一个执行就地切片(原始对象已修改)的方法 这就是我所拥有的: class MyList(list): def __init__(self, mylist = []): list.__init__(self) self.extend(mylist) def slice_it(self, x): self = self[:x] return self 然后我举例说明

我试图编写一个从Python
list
类继承的类,并且有一个执行就地切片(原始对象已修改)的方法

这就是我所拥有的:

class MyList(list):
    def __init__(self, mylist = []):
        list.__init__(self)
        self.extend(mylist)
    def slice_it(self, x):
        self = self[:x]
        return self
然后我举例说明:

>>> mylist = MyList(mylist=[1,2,3,4,5])
>>> mylist
[1, 2, 3, 4, 5]
>>> mylist.slice_it(3)
[1, 2, 3]
>>> mylist
[1, 2, 3, 4, 5]
我希望最后的输出是[1,2,3]。有什么想法吗?

您只需分配给局部变量
self
,这不会改变列表。您必须使用mutator方法,因此请尝试:

class MyList(list):
    def __init__(self, mylist = None):
        list.__init__(self)
        if mylist is not None:
            self.extend(mylist)
    def slice_it(self, x):
        self[:] = self[:x]
        return self
在行动中:

In [10]: mylist = MyList(mylist=[1,2,3,4,5])

In [11]: mylist
Out[11]: [1, 2, 3, 4, 5]

In [12]: mylist.slice_it(3)
Out[12]: [1, 2, 3]

In [13]: mylist
Out[13]: [1, 2, 3]
请注意,您实际上可以使用切片表示法来实现这一点:

In [30]: from itertools import islice
    ...: class MyList(list):
    ...:     def __init__(self, mylist = []):
    ...:         list.__init__(self)
    ...:         self.extend(mylist)
    ...:     def __getitem__(self, x):
    ...:         if isinstance(x, slice):
    ...:             self[:] = islice(self, x.start, x.stop, x.step)
    ...:             return self
    ...:         else:
    ...:             return list.__getitem__(self, x)
    ...:

In [31]: mylist = MyList(mylist=range(20))

In [32]: mylist[::2]
Out[32]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

In [33]: mylist
Out[33]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

In [34]: mylist[0]
Out[34]: 0

In [35]: mylist
Out[35]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
对于一个流畅的界面来说,这是怎么回事

In [36]: mylist = MyList(mylist=range(100))

In [37]: mylist[::2][:10]
Out[37]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

In [38]: mylist
Out[38]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

分配给
self
只分配一个局部变量;和其他变量赋值一样,它不会改变对象。@user2357112我知道,但这是我能做的最好的了。我也尝试不使用该行,但直接使用
返回self[:x]
。得到了相同的结果。如果您没有编写
MyList
类,而您只是有一个列表,希望进行变异以生成所需的最终状态,那么您会编写什么代码来实现这一点?在
slice\u it
中编写该代码。我认为在Python中就地修改列表不是一个好主意,无论是在方便性还是性能方面都是如此。@我不知道,在某些情况下它可能非常方便/高效。我不知道我是否会将子类
list
简单地添加一个这样做的方法,但我怀疑OP坚持使用某种流畅的接口。@DeliriousRecast当然可以,特别是如果您不知道默认参数语义的话。我甚至没有注意到它,老实说,我只是从OP中复制了它,不过,在这种情况下,它可能没那么糟糕,因为它在
\uuuuu init\uuuuuu
中从未真正发生过变异,但是,可能最好是安全的,不要使用它。@delirious莴苣无需删除,人们看到这些注释是很好的。编辑哦,太晚了:)