在Python中将单个元素列表视为标量

在Python中将单个元素列表视为标量,python,list,subclass,Python,List,Subclass,?是否可以定义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'] #

?是否可以定义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.\uuuu添加(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
功能。可能对你有帮助


为了解决您的编辑问题,一个更通用的解决方案将相当简单-不要重写
\uuuu add\uuuu()
函数,而是尝试重写
\uuuu getitem\uuuu()
,只要使用方括号操作符,就会调用该函数:

class CustomList(list):
    def __getitem__(self, y):
        if len(self) == 1:
            return self[0][y]
        else:
            return self[y]
但是,在尝试连接数组时,这可能会导致问题
list3+list1
会导致错误,因为
list1
不是一个iterable,当然,如果列表长度超过一个元素,您可以重写
\uuuuuuuuuuu
以简单地将第二个值添加为列表元素


使用上述声明的控制台输出:

>>> list1 = CustomList([2])
>>> list2 = CustomList([3])
>>> list3 = CustomList([4,5,6])
>>> print(list1 + list2)
5
>>> print(list2 + list3)
[3, 4, 5, 6]

是的,但实际上您需要覆盖您希望它使用的任何方法

当您在对象(如列表)上调用某些运算符时,最终会在这些对象上调用隐藏方法。在您给出的示例中,
result=list1+list2
,实际调用的函数是
list1.\uuuu添加(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
功能。可能对你有帮助


为了解决您的编辑问题,一个更通用的解决方案将相当简单-不要重写
\uuuu add\uuuu()
函数,而是尝试重写
\uuuu getitem\uuuu()
,只要使用方括号操作符,就会调用该函数:

class CustomList(list):
    def __getitem__(self, y):
        if len(self) == 1:
            return self[0][y]
        else:
            return self[y]
但是,在尝试连接数组时,这可能会导致问题
list3+list1
会导致错误,因为
list1
不是一个iterable,当然,如果列表长度超过一个元素,您可以重写
\uuuuuuuuuuu
以简单地将第二个值添加为列表元素


使用上述声明的控制台输出:

>>> list1 = CustomList([2])
>>> list2 = CustomList([3])
>>> list3 = CustomList([4,5,6])
>>> print(list1 + list2)
5
>>> print(list2 + list3)
[3, 4, 5, 6]

假设添加两个类意味着连接两个列表,您可以这样做(请注意_uadd _u方法以了解如何进行添加):


假设添加两个类意味着连接两个列表,您可以这样做(请注意_uadd _u方法以了解如何进行添加):



你希望加法做什么?与列表类似的连接?定义
类CustomList(list)
正是需要的,您遇到了什么问题?@MisterMiyagi“list1+list2”应该返回list1[0]和list2[0]的值之和。查看我的上一次编辑。我看到你想要什么,但看不到你的问题是什么。你不知道如何使操作员过载吗?如何根据列表的长度进行切换?如何对非标量列表使用基类行为?@MisterMiyagi我没有定义类的经验,但我可以将Green-clope-Guy示例应用于其他二进制运算符。但是,我不知道要重新定义什么方法(或者重载什么运算符),例如“print(list)”而不是“print(list[0])。您希望加法方法做什么?与列表类似的连接?定义
类CustomList(list)
正是需要的,您遇到了什么问题?@MisterMiyagi“list1+list2”应该返回list1[0]和list2[0]的值之和。查看我的上一次编辑。我看到你想要什么,但看不到你的问题是什么。你不知道如何使操作员过载吗?如何根据列表的长度进行切换?如何对非标量列表使用基类行为?@MisterMiyagi我没有定义类的经验,但我可以将Green-clope-Guy示例应用于其他二进制运算符。但是我不知道要重新定义什么方法(或者重载什么操作符),例如“print(list)”而不是“print(list[0])。
list
可以直接子类化,不需要编写所有的样板文件。
list
可以直接子类化,不需要编写所有的样板文件。添加可能会返回另一个
CustomList
,而不是一个普通的
list
。谢谢,这正是我想用算术运算符做的,但我仍然不知道如何使用类似的东西:list4=“CustomList[{'foo':'bar}]”,然后执行“print(list4['foo'])”而不是“打印(列表4[0]['foo'])”。请参阅我的编辑。如果您想使其像字典一样工作,那么您还可以重写
\uuu getitem\uuu()
方法,该方法在使用方括号运算符时激活。我在我的帖子中编辑了一个简单的例子,当然你应该做任何你需要做的事情,使它适合你的需要implementation@GreenCloakGuy伟大的我想我可以用你最后的例子。列表连接不是问题,因为我不打算使用子类替换标准列表类。添加可能会返回另一个
CustomList
,而不是普通的
List
。谢谢,这正是我想用算术运算符做的,但是,我不知道如何处理类似的内容:list4=“CustomList[{'foo':'bar'}]”,然后执行“print(list4['foo'])”而不是“print(list4[0]['foo'])”。看到我的爱德了吗