Python程序通常很短小精悍,而其他编程语言中需要写一堆代码的东西(就我所知)在Python中可以用一两行代码完成。 我正在尝试编写一个这样的程序,从字符串中提取每隔一个字母的字符。 我有这个可行的代码,但想知道是否有其他简洁的方法?
>>> s
'abcdefg'
>>> b = ""
>>> for i in range(len(s)):
... if (i%2)==0:
... b+=s[i]
...
>>> b
'aceg'
>>>
>>> 'abcdefg'[::2]
'aceg'
解释一下Python的分片符号 (slice notation):
>>> 'abcdefg'[::2]
'aceg'
>>>
切片表示法的格式为 [start:stop:step]
。因此,[::2]
告诉Python按照2的步幅来遍历字符串(这将返回每隔一个字符的字符)。
这里有一个关于列表和字符串的另一个例子:
sentence = "The quick brown fox jumped over the lazy dog."
sentence[::2]
这里的意思是:从字符串开头到结尾,返回每两个字符中的一个。
将返回以下内容:
'Teqikbonfxjme vrtelz o.'
colors = ["red", "organge", "yellow","green", "blue"]
colors[1:4]
would retrun:
['organge', 'yellow', 'green']
sentence[1:4]
,则从索引1(记住起始位置是索引0)开始,并在索引4之前停止。enumerate
函数。for i in range(len(foo)):
value = foo[i]
something with value and i
for i, value in enumerate(foo):
something with value and i
for i, c in enumerate(s):
if (i%2)==0:
b+=c
b = "".join(c for i, c in enumerate(s) if i%2 == 0)
b = s[::2]
那么简洁易读,但比你最初的做法好得多——当你想要做更复杂的事情时,例如if i%2 and i%3
(这不能映射到任何明显的切片),或者用c*2
将每个字母加倍(可以通过将两个切片一起压缩来完成,但这不是立即显然的),等等,同样的思路也适用。b = "".join([c for i, c in enumerate(s) if i%2 == 0])
。当然,在这里使用生成器最好。但只是想澄清一下。请不要误解我。 - brain stormstr.join
的情况下,实际上没有什么区别——如果 str.join
得到的不是 C 中的快速可索引对象,则会将其转换为列表,以便可以快速索引。事实上(特别是在 3.4 之前),列表推导甚至可能更快且使用更少的内存,这一点与直觉相反。但从概念上讲,我认为在不需要构建列表时最好不要构建它。(而且,除非你知道 str.join
在底层是如何工作的,否则你不会知道你需要它。) - abarnert>>> k = list(s)
>>> "".join(k[::2])
'aceg'
join
连接字符串比他现在的代码要好。 - rlms>>> s
'abcdefg'
>>> b = []
>>> for index, value in enumerate(s):
if index % 2 == 0:
b.append(value)
>>> b = "".join(b)
或者更好的是:
>>> b = "".join(value for index, value in enumerate(s) if index % 2 == 0)
这可以轻松地扩展到更复杂的条件:
>>> b = "".join(value for index, value in enumerate(s) if index % 2 == index % 3 == 0)