В строке Условное выражение или Функция - Pythonic? - PullRequest
3 голосов
/ 07 ноября 2011

У меня есть ситуация, когда я хотел бы условно вырезать строку из указанной позиции символа '@';условие: нарезать строку, если есть «@», иначе оставить ее нетронутой.Я придумал два способа, один с использованием функции, другой с помощью встроенного условного выражения.Какой метод является наиболее Pythonic?

Использование функции

>>> def slice_from_at(inp):
...     res = inp.find('@')
...     if res == -1:
...         return None
...     else:
...         return res     
>>> c = 'agent_address@agent_address'
>>> c[:slice_from_at(c)]
... 'agent_address'

Использование встроенного условного выражения

>>> c = 'agent_address@agent_address'
>>> c[:None if c.find('@') == -1 else c.find('@')]
... 'agent_address'

Хотя использование встроенного условного выражения является более кратким и,кто-то может поспорить, что он более экономичен - является ли метод функции более питонским, потому что он более читабелен?

Ответы [ 6 ]

5 голосов
/ 07 ноября 2011

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

Встроенное выражение может вызывать c.find('@') дважды, что неэффективно.

Как уже упоминал в комментариях Useless, для этого уже есть встроенные функции; вам действительно не нужно определять свою собственную функцию в этом случае:

agent,_,address = c.partition('@')

Кстати, обратный вызов - это функция, которая передается в качестве аргумента и вызывается позже. У вас нет обратного вызова, так как он не вызывается позже. Я думаю, что это нужно просто назвать функцию.

3 голосов
/ 07 ноября 2011

Большинство Pythonic?

Не изобретать велосипед, используйте str.partition()

def slice_from_at(inp):
    if '@' in inp:
        return inp.partition('@')[2]
    return inp

Если вас больше волнует скорость, чем читабельность, попробуйтеstr.rsplit():

def slice_from_at(inp):
    return inp.rsplit('@', 1)[-1]

Ни один из ваших примеров не содержит "обратного вызова".Не должны они.

Хорошо названная функция, которая делает одну вещь и делает это хорошо, примерно такая же Pythonic, как и получает.Если это подтверждается юнит-тестами, тем лучше.

0 голосов
/ 07 ноября 2011

Я кодирую так:

if '@' in c:
    c = c[:c.find('@')]

В большинстве случаев я не перемещаю 2 строки кода для разделения функций.

0 голосов
/ 07 ноября 2011

Я обычно предпочитаю строковые методы, когда они легко выполняют свою работу, но для полноты следует упомянуть регулярные выражения:

re.sub('^.*@', '', c)
0 голосов
/ 07 ноября 2011

Стилистическая причина, по которой [существует, но вы могли бы написать их самостоятельно], например, .partition() или .rsplit() чище, чем c[:slice_from_at(c)], что API slice_from_at() является низкоуровневым: он возвращает индекс взаданная строка, но этот индекс имеет смысл только для обрезки строки, так почему бы не вернуть нужный фрагмент (ы) строки напрямую?

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

  • zip() и enumerate() снижение потребности в for i in range(len(seq)): петлях.
  • substring in string, str.split(), затем str.partition().
0 голосов
/ 07 ноября 2011

А как насчет этого?

c.split('@')[0]
...