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不是轴列表,而是单个轴。
答案 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()