Обработка списков и одного элемента, а не типа списка - PullRequest
0 голосов
/ 06 февраля 2019

В 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, поскольку ось - это не список осей, а одна ось.

Ответы [ 4 ]

0 голосов
/ 06 февраля 2019

Не так много функций, которые ведут себя так, именно по той причине, которую вы указали.plt.subplots пытается обеспечить удобство для пользователей, создающих один субплот, или строку или столбец субплотов.Это поведение можно легко отключить с помощью параметра squeeze, и в этом случае axis станет двумерным массивом.

Вы можете сделать

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]

Всеслучаи, конкретные или общие, являются грязными.Наличие очень разных типов возвращаемых значений не является хорошим дизайном по этой точной причине.К сожалению, вам нужно найти какой-то способ компенсации, если функция не позволяет отключить его.

0 голосов
/ 06 февраля 2019

Простым методом может быть написание функции и вызов функции для возвращаемого значения.Функция может внутренне преобразовать результат в список, если он еще не является списком.

A Пример:

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]
0 голосов
/ 06 февраля 2019

Используя параметр squeeze и немного изменив свой код.

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()
0 голосов
/ 06 февраля 2019

Вы можете заключить вызовы в такие функции, как это:

>>> 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...