3

I have a situation where I would like to conditionally slice a string from the reported position of an '@' symbol; the condition being: slice the string if the '@' is there, else leave it untouched. I thought up two ways, one using a function, the other using an inline conditional expression. Which method is the most Pythonic?

Using a function

>>> 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'

Using an inline conditional expression

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

Although using the inline conditional expression is more terse and, some may argue more economical - is the function method is more Pythonic because it more readable?

4

6 回答 6

5

函数不仅可读性更强,而且可重用。

内联表达式可能调用c.find('@')两次,效率低下。

正如 Useless 在评论中提到的那样,已经有内置函数可以做到这一点;在这种情况下,您真的不需要定义自己的函数:

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

顺便说一句,回调是作为参数传入并稍后调用的函数。您没有回调,因为稍后不会调用它。我认为它应该被称为一个函数。

于 2011-11-07T09:45:41.163 回答
3

最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 一样。如果它支持单元测试,那就更好了。

于 2011-11-07T09:50:05.437 回答
0

我这样编码:

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

在大多数情况下,我不会将 2 行代码移入单独的函数。

于 2011-11-07T11:32:54.257 回答
0

这个怎么样?

c.split('@')[0]
于 2011-11-07T09:46:51.360 回答
0

[existing, but you could have write them yourself] 功能类似于.partition().rsplit()c[:slice_from_at(c)]API更简洁的文体原因slice_from_at()是低级的:它返回给定字符串的索引,但该索引仅对 cut 有意义字符串,那么为什么不直接返回所需的字符串片段呢?

通常,当存在更高级别的替代方案时,序列中的索引被认为是非pythonic,这可以从减少索引暴露的内置帮助器数量的增长中得到证明。想到的具体例子:

  • zip()enumerate()减少对for i in range(len(seq)):循环的需求。
  • substring in string, str.split(), 那么str.partition().
于 2011-11-07T11:15:35.113 回答
0

当它们轻松完成工作时,我倾向于更喜欢字符串方法,但为了完整起见,应该提到正则表达式:

re.sub('^.*@', '', c)
于 2011-11-07T11:18:25.780 回答