我经常遇到这个问题,如果没有一些非常简单和通俗的一行解决方案,我会感到惊讶.

假设我有一个方法或函数,它接受一个列表或其他一些iterable对象作为参数.我希望对对象中的每个项目执行一次操作.

有时,只有一个项目(例如,浮点值)被传递给该函数.在这种情况下,我的for循环不知道该怎么办.因此,我发现自己在代码中添加了以下代码片段:

from collections.abc import Sequence

def my_function(value):
   if not isinstance(value, Sequence):
      value = [value]

   # rest of my function

这是可行的,但似乎很浪费,也不太清晰.在搜索StackOverflow时,我还发现字符串被视为序列,因此如果参数错误,这段代码很容易中断.这感觉不是正确的方法.

我来自MATLAB背景,这在该语言中得到了巧妙的解决,因为标量被视为1x1矩阵.我希望,至少会有一个内置的,比如numpy's atleast_1d function,如果不是iterable,它会自动将任何东西转换成iterable.

推荐答案

简单的回答是没有,没有简单的内置功能.是的,如果你想让str(或bytes或类似字节之类的东西)作为标量值,它会变得更难看.Python希望调用方遵守接口契约;如果你说你接受序列,那么就这么说,调用方就有权包装任何单独的参数.

如果必须这样做,有两种明显的方法:

首先是让函数接受varargs而不是单个参数,并让调用者自行解压任何序列,这样就可以始终迭代接收到的varargs:

def my_function(*values):
    for val in values:
        # Rest of function

一个有单个项目的来电者用my_function(a, b)打电话给你,一个有序列的来电者用my_function(*seq)打电话给你.后者确实会产生一些开销,以便将序列解包到my_function接收的新tuple,但在许多情况下,这是可以接受的.

如果出于任何原因,这是不可接受的,另一种解决方案是使用自己的"确保可移植"转换器功能,遵循您关心的任何规则:

from collections.abc import ByteString

def ensure_iterable(obj):
    if isinstance(obj, (str, ByteString)):
        return (obj,)  # Treat strings and bytes-like stuff as scalars and wrap
    try:
        iter(obj)  # Simplest way to test if something is iterable is to try to make it an iterator
    except TypeError:
        return (obj,)  # Not iterable, wrap
    else:
        return obj  # Already iterable

my_function个可以用于:

def my_function(value):
   value = ensure_iterable(value)

Python相关问答推荐

在二维NumPy数组中,如何 Select 内部数组的第一个和第二个元素?这可以通过索引来实现吗?

根据Pandas中带条件的两个列的值创建新列

python的文件. truncate()意外地没有截断'

Python如何导入类的实例

如何在Python中解析特定的文本,这些文本包含了同一行中的所有内容,

Pythonquests.get(Url)返回Colab中的空内容

如何在Python中创建仅包含完整天数的月份的列表

具有不匹配列的2D到3D广播

在Matplotlib中通过特定的Y值而不是 colored颜色 来改变alpha/opacity

将标量值作为输入并输出矩阵的函数的积分

在多索引的Pandas数据帧中,有可能有一个值引用更高级别索引的列吗?

带极点数据帧的倒数值(&Q;)

如何使一个更有效的映射函数基于一个以另一个嵌套框架的索引和列名作为其数据集的嵌套框架?

如何在PANAS列中应用带有多个参数的自定义函数

Python开发依赖项

如何拟合返回2个输出的深度学习模型

已超过url:/Forecast的最大重试次数.无法在Fastapi应用程序上建立新连接:[WinError 10061]

窗口必须是整数0或更大,&q;与';30D';样式滚动计算有关

如何计算数据集中的类别值并将求和转换为新的数据集?

如何在Django中使用使用数学过滤器的If Else条件?