Python:在字符串列表中找到X到Y
我有一个大约100个元素的列表,这些元素实际上是电子邮件,每一行都是一个元素。这个列表有点变化,因为包含\n的行会被放到一个单独的元素里,所以我不能简单地用固定的值来切割。我需要一个可变的开始和结束短语(需要部分匹配,因为我的某个开始短语可能是Total Cost: $13.43
,所以我只会用Total Cost:
)。结束短语也是同样的道理。我也不想在返回的列表中包含开始和结束短语。总的来说:
>>> email = ['apples','bananas','cats','dogs','elephants','fish','gee']
>>> start = 'ban'
>>> stop = 'ele'
# the magic here
>>> print new_email
['cats', 'dogs']
注意事项
- 虽然电子邮件的格式不是完美的,但还是相对一致,所以开始/结束短语出现多次的可能性很小。
- 列表中也没有空元素。
解决方案
为了好玩,并且感谢大家的帮助,这里是我的最终代码:
def get_elements_positions(stringList=list(), startPhrase=None, stopPhrase=None):
elementPositionStart, elementPositionStop = 0, -1
if startPhrase:
elementPositionStart = next((i for i, j in enumerate(stringList) if j.startswith(startPhrase)), 0)
if stopPhrase:
elementPositionStop = next((i for i, j in enumerate(stringList) if j.startswith(stopPhrase)), -1)
if elementPositionStart + 1 == elementPositionStop - 1:
return elementPositionStart + 1
else:
return [elementPositionStart, elementPositionStop]
它返回一个列表,包含开始和结束元素的位置,如果找不到相应的值,默认返回0和-1。(0表示第一个元素,-1表示最后一个元素)。
解决方案-B
我做了一个小改动,现在如果列表描述的开始和结束位置之间只有一个元素,它会返回那个元素的位置作为整数,而不是列表,对于多行返回的情况仍然会返回列表。
再次感谢大家!
3 个回答
2
给你看看:
>>> email = ['apples','bananas','cats','dogs','elephants','fish','gee']
>>> start = 'ban'
>>> stop = 'ele'
>>> out = []
>>> appending = False
>>> for item in email:
... if appending:
... if stop in item:
... out.append(item)
... break
... else:
... out.append(item)
... elif start in item:
... out.append(item)
... appending = True
...
>>> out.pop(0)
'bananas'
>>> out.pop()
'elephants'
>>> print out
['cats', 'dogs']
我觉得我的版本比其他答案更容易读懂,而且不需要任何导入的东西 =)
4
一种基于 itertools
的方法:
import itertools
email = ['apples','bananas','cats','dogs','elephants','fish','gee']
start, stop = 'ban', 'ele'
findstart = itertools.dropwhile(lambda item: not item.startswith(start), email)
findstop = itertools.takewhile(lambda item: not item.startswith(stop), findstart)
print list(findstop)[1:]
// ['cats', 'dogs']
5
>>> email = ['apples','bananas','cats','dogs','elephants','fish','gee']
>>> start, stop = 'ban', 'ele'
>>> ind_s = next(i for i, j in enumerate(email) if j.startswith(start))
>>> ind_e = next(i for i, j in enumerate(email) if j.startswith(stop) and i > ind_s)
>>> email[ind_s+1:ind_e]
['cats', 'dogs']
>>> def get_ind(prefix, prev=-1):
it = (i for i, j in enumerate(email) if i > prev and j.startswith(prefix))
return next(it, None)
>>> start = get_ind('ban')
>>> start = -1 if start is None else start
>>> stop = get_ind('ele', start)
>>> email[start+1:stop]
['cats', 'dogs']
为了满足某些条件,当元素可能不在列表中的时候: