2010-06-02 64 views
0

我有一个100个左右的元素的列表,实际上是一个包含每行的电子邮件元素。这个列表有轻微的变化,因为其中有一个\ n的行被放在一个单独的元素中,所以我不能简单地使用固定值进行分片。我基本上需要一个可变的开始和结束短语(需要进行部分搜索,因为我的一个开始短语实际上可能是Total Cost: $13.43,所以我只会使用Total Cost:。)与结尾短语相同。我也不希望在返回的列表中包含开始/停止词组。总结:Python:在字符串列表中查找X到Y

>>> email = ['apples','bananas','cats','dogs','elephants','fish','gee'] 
>>> start = 'ban' 
>>> stop = 'ele' 

# the magic here 

>>> print new_email 
['cats', 'dogs'] 

注意

  • 虽然电子邮件不是完美的格式,它是相当一致的所以有一个渺茫的机会开始/停止短语会出现不止一次。
  • 也没有空白的元素。

SOLUTION

只是为了funzies并感谢这里大家的帮助是我的最终代码:

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是最后一个元素)。

SOLUTION-B

我做一个小的变化,现在如果列表被描述的开始和停止位置,导致仅有1元件之间它返回元件位置为整数,而不是一个列表您仍然获得多线回报。

再次感谢!

+0

你不需要返回列表,返回元组通常工作得很好。 [将list()'作为默认值做的事情完全不同。](http://docs.python.org/tutorial/controlflow.html#default-argument-values)。我的代码也是这样的原因是DRY。 – SilentGhost 2010-06-03 17:04:52

+0

是的,我仍然在研究整个“好Python程序员”的事情。我开始与Django一起学习Python,所以我觉得我可能错过了很多Python的小功能,但我正在学习。 – TheLizardKing 2010-06-03 17:29:17

回答

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'] 
+0

只有在开始短语之前没有停止短语的出现时,这才起作用。解决它不应该太难,但请牢记这一点。 – 2010-06-02 16:45:34

+0

@ a-levy:固定。 – SilentGhost 2010-06-02 16:48:32

+0

如果其中一个或两个短语不在数组中,这个工作是否会起作用? – 2010-06-02 16:52:02

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'] 
+0

Playin' – TheLizardKing 2010-06-02 17:05:27

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'] 

我认为我的版本太多了比其他答案更具可读性,不需要任何进口=)

+0

的积分如果您希望看到流程中的每一个小步骤,那么您的版本更具可读性。其他版本是用更多功能的编程风格编写的。他们不用小步骤指定算法,而是通过将较小的通用算法链接在一起来组成整个算法。这可能一开始就让人困惑,但是当你习惯它时,它是非常可读的! “itertools”解决方案采用了时间和时间算法来解决两行问题。一旦你开始思考功能,你可以更快地阅读和理解算法的实现。 – 2010-06-03 13:45:25

+0

它与“迷惑”无关;没有一个例子令人困惑。它与“显式比隐式更好”和“稀疏比密集更好”有关。 – 2010-06-03 18:56:41

相关问题