处理列表和一个元素不是列表类型

时间:2019-02-06 09:48:28

标签: python list

python中有许多函数可以返回元素列表。如果只有一个元素,则它们将返回该元素,而不是包含一个元素的列表。因此,for element in returnedList这样的代码不适用于只有一个元素的情况。

处理这种情况的正确方法是什么?我可以检查返回值是否不是列表,然后执行returnedList = [returnedList],但这很麻烦,而且由于许多函数的行为都如此,因此必须有一种更好的方法。

例如使用matplotlib:

import matplotlib.pyplot as plt

x = range(0, 10)
y = x
N = 2

f, axis = plt.subplots(N, 1, sharex=True)
for ax in axis:
    ax.plot(x,y)

plt.show()

将适用于N> 1,否则将不适用于N = 1,因为axis不是轴列表,而是单个轴。

4 个答案:

答案 0 :(得分:2)

完全出于您所说的原因,没有那么多函数会像那样运行。 plt.subplots试图为创建单个子图或子图的行或列的用户提供便利。可以使用squeeze参数轻松关闭此行为,在这种情况下,axis将成为2D numpy数组。

你可以

f, axis = plt.subplots(N, 1, sharex=True, squeeze=False)
for ax in axis.ravel():
    ax.plot(x,y)

ravel的调用可确保您在所有情况下都具有一维数组。

对于更通用的解决方案,您可以选择一些方法。如果结果的形状取决于输入,则可以使用if语句:

if N == 1: axis = [axis]

如果预先知道返回可迭代的返回类型,例如np.ndarray,则可以使用isinstance

if not isinstance(axis, np.ndarray): axis = [axis]

最后,您可以使用异常处理:

try:
    for ax in axis:
        ax.plot(x, y)
except TypeError:
    axis.plot(x, y)

可以改写以避免冗余:

try:
    iter(axis)
except TypeError:
    axis = [axis]

所有情况,无论具体还是一般,都是混乱的。由于这个确切的原因,具有非常不同类型的返回值不是一个好的设计。不幸的是,如果该功能不允许您将其关闭,则必须找到某种补偿方法。

答案 1 :(得分:1)

您可以像这样包装对这些函数的调用:

>>> from typing import Iterable
>>> def ensure_iter(a):
        if isinstance(a, Iterable):
            return a
        else:
            return [a]


>>> ensure_iter([])
[]
>>> ensure_iter('fred')
'fred'
>>> ensure_iter(1)
[1]

答案 2 :(得分:0)

一个简单的方法可以是编写一个函数并在返回的值上调用该函数。如果该函数还不是列表,则可以在内部将结果转换为列表。

示例:

a = [2,3,4]
b  = 1

def convert(a):
    return a if type(a) == list else [a]

print convert(a)
print convert(b)

输出:

[2, 3, 4]
[1]

答案 3 :(得分:0)

使用参数压缩,并稍微修改代码。

import matplotlib.pyplot as plt

x = range(0, 10)
y = x
N = 1

f, axis = plt.subplots(N, 1, sharex=True, squeeze=False)
for ax in axis:
    ax[0].plot(x,y)

plt.show()