#python #python-3.x
#python #python-3.x
Вопрос:
Я спрашиваю вас здесь о проблеме в названии, потому что я новичок в Python и особенно в создании listcomps.
Я хотел бы создать простую функцию для:
- проверьте, являются ли все аргументы
*args
списками - если нет, то значение преобразуется в список
- сгладить все с помощью
itertools
Ниже вы можете найти мой код:
import itertools
def lstfunc(*args):
lstargs = list(args)
for i in lstargs:
if not isinstance(i, list):
lstargs[lstargs.index(i)] = [i]
lstargs = list(itertools.chain.from_iterable(lstargs))
return lstargs
print(lstfunc([1, 2, 3], 4, 5))
Вывод: [1, 2, 3, 4, 5]
(правильно).
Мой вопрос в том, как создать listcomp из этой части:
for i in lstargs:
if not isinstance(i, list):
lstargs[lstargs.index(i)] = [i]
Я пытался:
import itertools
def lstfunc(*args):
lstargs = list(args)
lstargs = [[i] for i in lstargs if not isinstance(i, list)]
lstargs = list(itertools.chain.from_iterable(lstargs))
return lstargs
print(lstfunc([1, 2, 3], 4, 5))
Но, к сожалению, это только [4, 5]
повторный запуск.
В чем моя ошибка?
Ответ №1:
Нужный вам listcomp:
lstargs = [x if isinstance(x, list) else [x] for x in lstargs]
чтобы воспроизвести целое list
. Ваша попытка просто отфильтровала list
s, она не выбирала между переносом и не переносом и создавала оба. Вам не нужно предварительно преобразовывать args
в a list
, чтобы быть понятным, поэтому вы можете упростить функцию до простого:
def lstfunc(*args):
# Save eager conversion to temp list by using genexpr instead of listcomp
lstargs = (x if isinstance(x, list) else [x] for x in args) #
return list(itertools.chain.from_iterable(lstargs))
Комментарии:
1. @Konrad: Всегда пожалуйста. Предупреждаю: для полностью универсального кода вам, вероятно, лучше импортировать
Iterable
ABC изcollections.abc
и изменитьisinstance(x, list)
наisinstance(x, Iterable)
(возможноisinstance(x, Iterable) and not isinstance(x, (str, ByteString))
, еслиstr
bytes
bytearray
ожидаются аргументы // , хотя это довольно подробно), Поэтому вы не оборачиваете такие вещи, какtuple
,set
, случайные итераторы и т. Д.list
Если кто-то звонитlstfunc((2, 3, 5), range(3), (x ** 2 for x in [10, 11, 12]))
, вам, вероятно, нужен вывод[2, 3, 5, 0, 1, 2, 100, 121, 144]
.2. пожалуйста, найдите мой ответ ниже. Что вы думаете? Это хорошее решение или я должен знать о чем-то потенциально нежелательном?
Ответ №2:
После долгих мучений я нашел на самом деле самое простое и питоновское решение (я думаю)! Мне нужна была функция выше, чтобы создать одномерный список, чтобы передать его другой функции. Однако в этом нет необходимости. Мне просто нужен был оператор распаковки:
def testfunc(*args):
print(args)
testfunc(*[1, 2, 3], 4)
Вывод: (1, 2, 3, 4)
.
Это решение автоматически сглаживает все значения в 1D чистую итерацию (кортеж, я думаю).
Комментарии:
1. Вот почему важно также объяснить вашу реальную проблему, а не просто вопрос о вашем предпринятом решении. См xyproblem.info
2. Спасибо, теперь я запомню :).