Как правило, строки (plain и unicode) являются единственными итерациями, которые вы, тем не менее, хотите рассматривать как «отдельные элементы» - встроенная функция basestring
существует ОСОБЕННО, чтобы позволить вам тестировать строки любого типа с isinstance
, поэтому это очень непонятно для этого особого случая; -).
Итак, мой предложенный подход для наиболее общего случая:
if isinstance(input, basestring): input = [input]
else:
try: iter(input)
except TypeError: input = [input]
else: input = list(input)
Это способ ОБРАБОТАТЬ КАЖДЫЕ итерируемые ИСКЛЮЧИТЕЛЬНЫЕ строки как список напрямую, строки и числа и другие не итерируемые как скаляры (для нормализации в списки из одного элемента).
Я явно делаю список из всех видов итераций, поэтому вы ЗНАЕТЕ, что в дальнейшем вы сможете выполнять КАЖДЫЙ трюк со списком - сортировку, повторение более одного раза, добавление или удаление элементов для упрощения итерации и т. Д., Все без изменения АКТУАЛЬНЫЙ входной список (если список действительно был ;-). Если все, что вам нужно, это один простой цикл for
, тогда этот последний шаг не требуется (и действительно бесполезен, если, например, ввод представляет собой огромный открытый файл), и я бы предложил вместо этого вспомогательный генератор:
def justLoopOn(input):
if isinstance(input, basestring):
yield input
else:
try:
for item in input:
yield item
except TypeError:
yield input
теперь в каждой функции, нуждающейся в нормализации аргументов, вы просто используете:
for item in justLoopOn(input):
Вы можете использовать вспомогательную функцию нормализации даже в другом случае (где вам нужен реальный список для дальнейших гнусных целей); на самом деле, в таких (более редких) случаях вы можете просто сделать:
thelistforme = list(justLoopOn(input))
так, чтобы (неизбежно) логика нормализации с некоторой шероховатостью была в ОДНОМ месте, как и должно быть! -)