Python:在字符串列表中找到X到Y

0 投票
3 回答
1154 浏览
提问于 2025-04-15 23:27

我有一个大约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']

为了满足某些条件,当元素可能不在列表中的时候:

撰写回答