假设我有一些对象x
可能是数据类型的单个实例(例如float
),或者它可能是float
类型的列表。
有什么我可以确保将x
包装成一个列表,如果需要可能是一个单例列表,而不检查它的类型或做类似的事情。
我希望list(x)
之类的东西能够始终有效,无论x
是否是单身,但这不起作用,因为单身不可迭代。
编辑:请参阅my answer below进行详细说明。
同时,我不想定义自己的函数来构造来自singeltons的列表,我也不希望像这样内联任何内容:
from collections import Iterable
y = [x] if not isinstance(x, Iterable) else list(x)
如果没有比这更简洁的话,那没关系。我正在寻找一些已经内置到语言中的干净方法。
我确信有些人可能认为isinstance
方法干净而且很好,但我特别想找到更简洁的东西,不要求我事先写下任何新东西。我在搜索文档页面时找不到任何内容,而且我不确定如何向搜索引擎提出这个问题。
答案 0 :(得分:5)
这是你没有问过的问题的答案,但也许应该有。我只能猜测,因为你没有给出相关的背景。
我如何处理违反我的界面合约的传递给我的论据?
你不应该尝试。如果我打电话给sum(2)
我正确
TypeError:'int'对象不可迭代
因为sum
期待迭代,我没有给它一个。如果您担心有人会同时打电话
my_function(2.2)
my_function([2.2, 4.4])
正确的反应是引发TypeError,而不是尝试为调用者修补一些东西,因为只要你修复第一个案例,就会有人调用
my_function([2.2, 'loretta'])
你还覆盖那个案子吗?如果他们向您提供自我参考列表怎么办?如果你来自强类型的语言背景,那么滥用Python就会有很强的诱惑力,因此它就像Java一样。这只会产生糟糕的Python代码:你在缺陷之上堆积了一个黑客。
“类型安全”也有点像can,否则double sqrt(float)
不会返回域错误,但确实如此。 sqrt
应该取其参数的绝对值吗?呼叫签名中的掩码错误仅确保缺陷未被发现,然后在您获得无法预期的无效参数时稍后中断。
答案 1 :(得分:1)
在使用Python获得更多经验之后重新审视这个问题,我发现了一个解决方案,但它违反了我没有定义函数的必要属性。
def make_list_containing(*args):
return list(args)
然后make_list_containing(3)
或make_list_containing('foo')
表现得像预期的那样(与list
构造函数相反,你必须改变你的直觉学习如何期待它采取行动)。
令我感到惊讶的是,list
作为构造函数与"转换为list
类型"同义。而不是"放入list
对象实例"。
我可以看到构造函数的多态行为在单例也是可迭代的情况下可能是模糊的,比如字符串。但是,为什么不支持"放入列表"非可迭代单例的行为?
另一件事是,至少在我看来,我所描述的方法似乎更多一致,更加坚持到最不惊讶。
使用make_list_containing
,您知道您总是会返回一个列表,并且它将包含传入的元素。只要您使用所需的格式传递它们那么这正是你要走出去的。考虑:
In [34]: make_list_containing(*'foo')
Out[34]: ['f', 'o', 'o']
In [35]: make_list_containing('foo')
Out[35]: ['foo']
或
In [40]: make_list_containing(*enumerate(range(3)))
Out[40]: [(0, 0), (1, 1), (2, 2)]
In [41]: make_list_containing(enumerate(range(3)))
Out[41]: [<enumerate at 0x7f61a7f0fd70>]
现在 对我来说似乎更直观了。预先*
正是我应该如何&#34;去迭代&#34;作为参数的东西中的项目。如果我不愿意选择那个,那么我必须将'foo'
视为单身,并计划在函数调用内部处理其元素或迭代。
在这次谈话中令人沮丧的一件事是,仅仅因为Python 的这种惯例是旧的,人们似乎将其与意义混为一谈并不奇怪。但这是对意外的狭隘定义。是的,当我解雇翻译时,我不再感到惊讶了#34;当list('foo')
给我['f', 'o', 'o']
时。但我仍然感到惊讶的是,这是构造函数的语言接口选择,与list
一样重要。这让我感到惊讶,因为它似乎有更多的设计弱点而不是优势,并且最初用来证明它的合理性是固定语法的光滑,而不是思想的清晰度。
此时它偏离了意见区太远,我显然可以理解,由于压倒性的历史动力,这在Python中不会改变。但我的问题的精神仍然是关于这个非常合理的观点。这不是一个懒惰的问题&#34;或者&#34;只需编写一个包装函数并继续前进即可。因为大多数评论似乎都希望如此。
答案 2 :(得分:0)
我不知道内置的任何内容。您的解决方案对我来说似乎是最好的选择,尽管您可能希望使用序列ABC而不是Iterable。