Python程序通常简短明了,在其他编程语言中通常需要一堆行的东西(据我所知)可以在Python中用一两行完成。我正在尝试编写的一个程序是从字符串中每隔一个字母提取一个。我有这个工作代码,但想知道是否有其他简洁的方法?
>>> s
'abcdefg'
>>> b = ""
>>> for i in range(len(s)):
... if (i%2)==0:
... b+=s[i]
...
>>> b
'aceg'
>>>
>>> 'abcdefg'[::2]
'aceg'
使用解释Python';s切片表示法:
>>> 'abcdefg'[::2]
'aceg'
>>>
切片表示法的格式为[start:stop:step]
。因此,[::2]
告诉Python按2的顺序遍历字符串(这将每隔一个字符返回一次)。
正确的方法是像其他答案一样对字符串进行切片。
但是,如果您想要一种更简洁的方式来编写您的代码,它可以解决类似的问题,而这些问题并不像切片那么简单,那么有两个技巧:理解和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
接下来,任何以空对象开始、经过可迭代对象(字符串、列表、迭代器等)并将值放入新的可迭代对象的循环,可能通过if
过滤器或转换值的表达式来运行值,都可以很容易地转化为理解。
虽然Python对列表、集合、dicts和迭代器有理解,但它对字符串没有理解——但str.join
解决了这一问题。
所以,把它放在一起:
b = "".join(c for i, c in enumerate(s) if i%2 == 0)
没有b = s[::2]
那么简洁或可读……但比你刚开始的要好得多——当你想做更复杂的事情时,同样的想法也有效,比如if i%2 and i%3
(它不映射到任何明显的切片),或者用c*2
将每个字母加倍(可以通过将两个切片压缩在一起来完成,但这并不明显),等等。
这里是列表和字符串的另一个例子:
sentence = "The quick brown fox jumped over the lazy dog."
sentence[::2]
这里我们要说的是:从开始到结束取整个字符串,并每隔2个字符返回一次。
将返回以下内容:
'Teqikbonfxjme vrtelz o.'
你可以对列表做同样的事情:
colors = ["red", "organge", "yellow","green", "blue"]
colors[1:4]
将重试:
['organge', 'yellow', 'green']
我读取切片的方式是:如果我们有sentence[1:4]
从索引1开始(记住起始位置是索引0),在索引4 之前停止
您可以尝试使用slice和join:
>>> k = list(s)
>>> "".join(k[::2])
'aceg'
实际上,切片是最好的方法。然而,也有一些方法可以改进现有代码,不是缩短代码,而是使其更Python化:
>>> 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)