2010-06-02 60 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

相關問題