我有一种情况,我想有条件地切割一个字符串 报告“@”符号的位置;条件是:切割字符串if '@'在那里,否则保持不变。我想了两个方法,一个使用a 函数,另一个使用内联条件表达式。是哪种方法 大多数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'
虽然使用内联条件表达式更简洁,但有些可能 认为更经济 - 功能方法更多是Pythonic,因为它更多 可读?
答案 0 :(得分:5)
功能不仅更具可读性,而且可以重复使用。
内联表达式可能会调用c.find('@')
两次,效率很低。
正如Useless在评论中所提到的,已经有内置函数来执行此操作;在这种情况下,你真的不需要定义自己的函数:
agent,_,address = c.partition('@')
顺便说一句,回调是一个作为参数传入并稍后调用的函数。您没有回调,因为它以后没有被调用。我认为它应该被称为函数。
答案 1 :(得分: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一样。如果它通过单元测试进行备份,那就更好了。
答案 2 :(得分:0)
相反怎么样?
c.split('@')[0]
答案 3 :(得分:0)
.partition()
或.rsplit()
这些函数[现有,但您可以自己编写]的风格原因比c[:slice_from_at(c)]
slice_from_at()
的{{1}}的API更清晰-level:它返回一个索引到它给出的字符串中,但是该索引只对剪切字符串有意义,那么为什么不直接返回字符串所需的片段呢?
通常,当存在更高级别的替代方案时,序列中的索引被认为是非语言的,这可以通过减少暴露于索引的内置助手的数量来证明。想到的具体例子:
zip()
和enumerate()
减少了对for i in range(len(seq)):
循环的需求。substring in string
,str.split()
,然后str.partition()
。答案 4 :(得分:0)
我倾向于喜欢字符串方法,但是为了完整性,应该提到正则表达式:
re.sub('^.*@', '', c)
答案 5 :(得分:0)
我这样编码:
if '@' in c:
c = c[:c.find('@')]
在大多数情况下,我不会将2行代码移到单独的函数中。