#python #lambda #map-function
#python #лямбда #map-функция
Вопрос:
Сократите это, не заходя пока в приложение. Вот мои данные: (список чисел и строк)
mylist=[20201209, 7100.0, 'paypal', 400.0, 'out', 'monthly', 'Paypal', 100.61676684696863, '']
Мне нужно преобразовать это в строку слов, разделенных табуляциями, где я определил размер табуляции, потому что я пытаюсь напечатать столбцы (используя функцию переноса в модуле textwrap. Но моя проблема находится до этого этапа).
это подвыражение работает нормально: lambda x: (x,str(round(x,2))) [type(x)!=str]
Но когда я помещаю его в (перечисленную) функцию отображения следующим образом: list(map(lambda x: (x,str(round(x,2))) [type(x)!=str],mylist)
Я понимаю это:
Ошибка типа: тип str не определяет метод round
, как будто он пытается разобрать str ( как str.
Я использовал этот лямбда-формат, потому что его легче всего читать. Использование более традиционного формата, такого как list(map(lambda x: str(round(x,2)) if type(x)!=str else x,mylist))
работает нормально. Но лямбды должны быть краткими, и я хотел бы избежать их if
и else
ключевых слов, если смогу. Возможно, этот формат устарел в версии 3.7.7? Официальные документы на этот счет довольно загадочны.
Что касается приложения, то последнее выражение, которое я бы использовал, это: c='t'.join(list(map(lambda x: (x,str(round(x,2))) [type(x)==str],mylist)))
wrapper.tabsize=2
print(wrapper.wrap(c)[0])
Это из списка списков, которые будут составлять столбцы. Я все еще новичок в Python, поэтому, если есть более чистый способ сделать это, не стесняйтесь, дайте мне знать! (хотя делать это сложным способом — хорошая практика. В какой-то библиотеке для этого может быть однострочник.)
Комментарии:
1. Я бы не стал искать
one-liner for this in some library
— сначала заставить его работать, развернуть, если слишком медленно, профилировать и реорганизовать. Не начинайте с последнего шага.
Ответ №1:
Работает ли это?
>>> list(map(lambda x: {str: lambda y: y}.get(type(x), lambda y: str(round(y, 2)))(x), mylist))
['20201209', '7100.0', 'paypal', '400.0', 'out', 'monthly', 'Paypal', '100.62', '']
# Hint: This solves your problem, but dont do this! Read on..
Дело в том, что уверенные однострочники — это здорово. Конечно map
, выглядит компактно (по крайней мере, здесь это не так). Но предпочитаю делать то, что доступно для чтения, доступно в обслуживании и, по сути, просто.
Я бы все же посоветовал вам придерживаться вашей другой версии (слегка измененной, чтобы сделать ее более питонической).:
result = [str(round(x, 2)) if isinstance(x, str) else x for x in mylist]
#yours = list(map(lambda x: str(round(x,2)) if type(x) != str else x, mylist))
# ^ indented so you can compare which one is compact.
.. и, пожалуйста, сравните это с чудовищностью первой строки в этом ответе.
Наконец: (something(x)) [type(x)!=str]
не делает то, что вы думаете. Он полностью оценит something(x)
(и именно поэтому вы сталкиваетесь с ошибкой), используйте возвращаемое значение ( result
), а затем попробуйте что-то вроде: result.__getitem__(boolean_value)
.
Комментарии:
1. есть над чем подумать, спасибо! У меня еще не было возможности углубиться в понимание списков, но он, безусловно, выглядит чище и содержит списки. были в моем списке задач. Почему