将单个元素列表视为 Python 中的标量
Treat a single element list as a scalar in Python
¿是否可以定义 python 列表的子类,允许使用单元素列表变量,就像它们是标量一样?
例如我希望能够做到:
class CustomList(list):
...
...
list1 = CustomList([2])
list2 = CustomList([3])
list3 = CustomList([4,5,6])
list4 = CustomList([{'foo':'bar'}])
list1 #should return list1[0]
list4['foo'] #should return list4[0]['foo'] = 'bar'
list1 + list2 #should return list1[0] + list2[0] = 5
但保持正常使用列表的能力:
for i in list3:
print list[i]
是的,但您实际上需要重写您希望它使用的任何方法。
当您在列表等对象上调用某些运算符时,您最终会在这些对象上调用隐藏方法。在你给出的例子中,result = list1 + list2
,实际调用的函数是list1.__add__(list2)
。如果需要,您可以继承 list
并覆盖这些方法。例如:
class CustomList(list):
def __add__(self, value):
if len(self) == 1 and len(value) == 1:
return self[0] + value[0]
else:
return CustomList(list.__add__(self, value))
将 list1
和 list2
视为标量,如果它们的长度均为 1,否则参考正常的 list
功能。 This Whosebug answer on subclassing list
可能对您有所帮助。
为了解决您的编辑问题,更通用的解决方案将相当简单 - 不要覆盖 __add__()
函数,而是尝试覆盖 __getitem__()
,只要您使用方括号运算符就会调用它:
class CustomList(list):
def __getitem__(self, y):
if len(self) == 1:
return self[0][y]
else:
return self[y]
但是,这可能会在尝试连接数组时引起问题; list3 + list1
会导致错误,因为 list1
不是可迭代对象,当然你可以重写 __add__
以简单地将第二个值添加为列表元素(如果列表的长度超过一个元素) .
使用上述声明的控制台输出:
>>> list1 = CustomList([2])
>>> list2 = CustomList([3])
>>> list3 = CustomList([4,5,6])
>>> print(list1 + list2)
5
>>> print(list2 + list3)
[3, 4, 5, 6]
假设通过添加两个 类 你的意思是连接两个列表,你可以做这样的事情(注意 __add__ 方法以了解如何添加):
from collections import MutableSequence
class CustomList(MutableSequence):
def __init__(self, data=[]):
self._list = data
def __add__(self, newlist):
return self._list + newlist._list
def __len__(self):
return len(self._list)
def __getitem__(self, i):
return self._list[i]
def __delitem__(self, i):
del self._list[i]
def __setitem__(self, i, val):
self._list[i] = val
def __str__(self):
return str(self._list)
def insert(self, i, val):
self._list.insert(i, val)
¿是否可以定义 python 列表的子类,允许使用单元素列表变量,就像它们是标量一样?
例如我希望能够做到:
class CustomList(list):
...
...
list1 = CustomList([2])
list2 = CustomList([3])
list3 = CustomList([4,5,6])
list4 = CustomList([{'foo':'bar'}])
list1 #should return list1[0]
list4['foo'] #should return list4[0]['foo'] = 'bar'
list1 + list2 #should return list1[0] + list2[0] = 5
但保持正常使用列表的能力:
for i in list3:
print list[i]
是的,但您实际上需要重写您希望它使用的任何方法。
当您在列表等对象上调用某些运算符时,您最终会在这些对象上调用隐藏方法。在你给出的例子中,result = list1 + list2
,实际调用的函数是list1.__add__(list2)
。如果需要,您可以继承 list
并覆盖这些方法。例如:
class CustomList(list):
def __add__(self, value):
if len(self) == 1 and len(value) == 1:
return self[0] + value[0]
else:
return CustomList(list.__add__(self, value))
将 list1
和 list2
视为标量,如果它们的长度均为 1,否则参考正常的 list
功能。 This Whosebug answer on subclassing list
可能对您有所帮助。
为了解决您的编辑问题,更通用的解决方案将相当简单 - 不要覆盖 __add__()
函数,而是尝试覆盖 __getitem__()
,只要您使用方括号运算符就会调用它:
class CustomList(list):
def __getitem__(self, y):
if len(self) == 1:
return self[0][y]
else:
return self[y]
但是,这可能会在尝试连接数组时引起问题; list3 + list1
会导致错误,因为 list1
不是可迭代对象,当然你可以重写 __add__
以简单地将第二个值添加为列表元素(如果列表的长度超过一个元素) .
使用上述声明的控制台输出:
>>> list1 = CustomList([2])
>>> list2 = CustomList([3])
>>> list3 = CustomList([4,5,6])
>>> print(list1 + list2)
5
>>> print(list2 + list3)
[3, 4, 5, 6]
假设通过添加两个 类 你的意思是连接两个列表,你可以做这样的事情(注意 __add__ 方法以了解如何添加):
from collections import MutableSequence
class CustomList(MutableSequence):
def __init__(self, data=[]):
self._list = data
def __add__(self, newlist):
return self._list + newlist._list
def __len__(self):
return len(self._list)
def __getitem__(self, i):
return self._list[i]
def __delitem__(self, i):
del self._list[i]
def __setitem__(self, i, val):
self._list[i] = val
def __str__(self):
return str(self._list)
def insert(self, i, val):
self._list.insert(i, val)