У меня есть случай, когда я генерирую понимание элемента с кардинальностью, отличной от входного источника. Эта мощность не должна быть кратной исходной (определяемой данными), а должна определяться условиями. Некоторые элементы исходного источника могут быть преобразованы в один элемент в месте назначения, тогда как другие могут быть преобразованы в несколько элементов или даже ни в один.
Существующие подходы
Несколько вопросов касаются смежных ситуаций, но не совсем одинаковых:
- Понимание списка: возврат двух (или более) элементов для каждого элемента [дубликат]
Как я могу получить простой результат из списка вместо вложенного списка?
Первый из них обращается к пониманию, длина которого в точности кратна длине источника. Второй обеспечивает способ создания плоских списков из результата, который имел списки списков, с помощью сокращения или с помощью двойной итерации в самом понимании. Обратите внимание, что в этом случае оба на самом деле будут создавать нерегулярное количество элементов (не кратное исходному), но на основе данных, а не на основе условий.
< h1>Простая проблема
У меня есть список строк, в которых будет число или два числа, разделенные дефисом, скажем:
Код: Выделить всё
['1', '2', '2-3', '3-1', '4-5']
Код: Выделить всё
['1', '2', '2', '3', '3', '1', '4', '5']
Решение 1 — паршивое
Код: Выделить всё
>>> a = ['1', '2', '2-3', '3-1', '4-5']
>>> '-'.join(a)
'1-2-2-3-3-1-4-5'
>>> '-'.join(a).split('-')
['1', '2', '2', '3', '3', '1', '4', '5']
- Я использую списки. На самом деле в моем упражнении используются словари, списки кортежей и тому подобные парные коллекции данных. Я мог бы присоединиться к некоторым из этих компонентов, но полностью потерял бы связь с другими частями исходных данных.
- Это хакерски, некрасиво и, вероятно, неэффективно.
Код: Выделить всё
>>> a = ['1', '2', '2-3', '3-1', '4-5']
>>> reduce(lambda acc, elem: acc+elem, (x.split('-') for x in a))
['1', '2', '2', '3', '3', '1', '4', '5']
Более сложная проблема
Что, если бы у меня был просто список чисел и я хотел бы генерировать ответы разной длины в зависимости от значений? Здесь я перехожу к спискам чисел, чтобы не мешать ответам на манипуляции со строками.
Теперь мне нужен список результатов, в который помещается число, если оно нечетное, и число и его половина, если даже:
Код: Выделить всё
>>> a = [1, 2, 3, 4, 5]
>>> # Magic code
[1, 1, 2, 3, 2, 4, 5]
Решение 0. Не хватает старого доброго C?
Код: Выделить всё
>>> a = [1, 2, 3, 4, 5]
>>> res = []
>>> for x in a:
... if x % 2:
... res.append(x)
... else:
... res.append(x//2)
... res.append(x)
...
>>> res
[1, 1, 2, 3, 2, 4, 5]
Решение 1. Сглаживание многомерного списка
Код: Выделить всё
>>> a = [1, 2, 3, 4, 5]
>>> [x if x % 2 else [x//2, x] for x in a]
[1, [1, 2], 3, [2, 4], 5]
Код: Выделить всё
>>> a = [1, 2, 3, 4, 5]
>>> [[x] if x % 2 else [x//2, x] for x in a]
[[1], [1, 2], [3], [2, 4], [5]]
Код: Выделить всё
>>> a = [1, 2, 3, 4, 5]
>>> reduce(lambda acc, elem: acc+elem, ([x] if x % 2 else [x//2, x] for x in a))
[1, 1, 2, 3, 2, 4, 5]
Мне нужно решение, которое просто передает в цель переменное количество элементов, рассчитанное на основе каждого исходного элемента. Причина, по которой это должно быть похоже на выражение, заключается в том, что оно встроено в более широкое выражение. Поэтому, несмотря на мое огромное уважение к ним, пожалуйста, никаких императивных решений Кернигана и Ритчи.
Редактировать
Некоторые участники упомянули, что я «готов использовать сокращение ». Я пытался дать понять, что ищу что-то другое. Мне нравится сокращение и все функциональные возможности, но использование ресурсов оправдано только тогда, когда данные поступают «как есть».
Что касается читаемости и необходимости , ничего против. Я работаю целый день на Python и C. Просто for больше говорит о том, «как», тогда как понимание больше о том, «что». Я думаю, что читаемость — это, в конечном счете, вопрос предпочтений:
Код: Выделить всё
Beautiful is better than ugly.
Explicit is better than implicit.
...
Я хотел бы особо отметить и поблагодарить jsbueno. Вы делаете правильные выводы. доход потрясающий, и это часть моей личной цепочки инструментов для повышения производительности, поскольку «Pythonicity» — только моя цель №2.
Еще одно спасибо Догберту. Ваше предложение было тем, что я считаю правильным решением. Должен признаться, что у меня уже было решение, когда я опубликовал это, и разница между вашим и моим просто квадратная и круглая.
В остальном, если подход «пока это работает", то я думаю, что многие вопросы повторяются, и да, путь из Кембриджа в Лондон может проходить через Гонолулу, "пока мы туда добираемся".
Я злоупотребил этим термином «Пифонический», даже не зная на 100%, что это значит. Я пытался не использовать библиотеки и оставить их «родными».
Вот мое решение:
Код: Выделить всё
>>> a = [1, 2, 3, 4, 5]
>>> [ x for i in a for x in ((i,) if i % 2 else (i // 2, i)) ]
[1, 1, 2, 3, 2, 4, 5]
Подробнее здесь: https://stackoverflow.com/questions/789 ... f-elements