2011-01-05 82 views
1

我有一個類似於['ONE', 'TWO', 'SEVEN', 'TWELVE', 'ONE', 'SEVEN']的字符串列表。給定一個字符串,我知道是在列表中,是否有一種簡單的方法來返回該字符串後面的所有元素的迭代(如果沒有任何內容跟隨它,則返回None)?Python:獲取列表中指定元素後面的項目

所以,輸入'ONE'將返回['TWO', 'SEVEN']和輸入'SEVEN'將返回['TWELVE', None]

我目前的做法是做這樣的事情:

follows = [] 
while test_string in string_list: 
    index = string_list.index(test_string) 
    if index + 1 < len(string_list): 
     follows.append(string_list[index+1]) 
     string_list = string_list[index+1:] 
    else: 
     follows.append(None) 
     string_list = [] 

但這似乎過於繁瑣。如果這是最好的方法,我可以接受它。如果有更清潔的方式,我很樂意學習它。

+0

特殊情況不是夠特別。當正常結果是以下元素的列表時,表示「沒有元素跟隨這個」的正確方法是**沒有元素的列表**(即'[]')。 – 2011-01-06 00:50:27

+0

我查看了其他答案,並意識到花了相當大的努力試圖瞭解你所問的問題後,我得出了一個完全不同的結論,從其他人那裏得到了你想要的東西。請嘗試在未來更加清晰。 :/ – 2011-01-06 00:55:19

回答

3

如何像:

>>> a = ['ONE', 'TWO', 'SEVEN', 'TWELVE', 'ONE', 'SEVEN'] 
>>> [a[x+1] if x+1 < len(a) else None for x in range(len(a)) if a[x] == 'ONE'] 
['TWO', 'SEVEN'] 
+0

雖然你應該更新這是一個可迭代的,當你在它的時候,你可能會使用'xrange'。 =) – milkypostman 2011-01-05 23:13:58

+0

這是完美的。我總是發現回去閱讀python的列表推導比任何帶條件的循環更容易。當我沒有看到寫作方法時,它會殺死我,我認爲它應該是可能的。謝謝。 – Wilduck 2011-01-05 23:19:29

+0

@dcurtis:我儘量寫出答案,儘可能在Python 2.x和Python 3.x中工作。 Python 3.x沒有'xrange()'。 – 2011-01-05 23:19:48

1
l = ['ONE', 'TWO', 'SEVEN', 'TWELVE', 'ONE', 'SEVEN'] 
k = 'ONE' 
[l[i+1] if i<len(l)-1 else None for i,e in enumerate(l) if e==k] 
+0

這會對'k ==「SEVEN」'失敗。 – 2011-01-05 23:11:29

+0

現在修復,謝謝。 – infrared 2011-01-05 23:12:39

1

也許這?

from itertools import izip 
[b for a, b in izip(string_list, string_list[1:] + [None]) if a == test_string] 
+0

雖然test_string ==''SEVEN''不會失敗,但它不會將'None'加到最後。 – Wilduck 2011-01-05 23:16:36

+0

@Wilduck:也許你有一箇舊版本的頁面?老版本沒有添加'None',但從來就沒有失敗的'test_string ==「SEVEN」'(注意'izip()'最短序列終止)版本。 – 2011-01-05 23:18:52

+0

我的確有舊版本。我提到你提到紅外線的答案會因爲test_string ==「SEVEN」而失敗。無論如何,你有我的讚賞。感謝您的迴應。 – Wilduck 2011-01-05 23:39:39

1

呃......感覺像發電機可能是一件好事。

>>> def follows(list, match): 
...  i = iter(list) 
...  x = next(i) 
...  while x: 
...   if x == match: 
...    try: 
...     yield next(i) 
...    except StopIteration: 
...     yield None 
...   x = next(i) 
... 
>>> [x for x in follows(['ONE', 'TWO', 'SEVEN', 'TWELVE', 'ONE', 'SEVEN'], 'SEVEN')] 
['TWELVE', None] 
>>> [x for x in follows(['ONE', 'TWO', 'SEVEN', 'TWELVE', 'ONE', 'SEVEN'], 'ONE')] 
['TWO', 'SEVEN'] 

但是更清潔?我猜想,味道的問題。

+1

這。它比上面的列表理解更具可讀性,並有可能超越它們以啓動。例如,[「一」,「一」,「二」,「七」,「十二」,「ONE」,「七」]應該返回['ONE - – 2011-01-06 05:22:18

+0

這如果目標在列表中連續出現兩次失敗','TWO','SEVEN'],而是返回['ONE','SEVEN']。 – 2011-01-06 20:58:21

+0

@Hugh:取決於。該邊緣案例沒有在規範中定義。我聲稱我的解決方案符合規格。 :) – 2011-01-06 22:10:46

0

的過程是:

  1. 查找元件的第一索引。
  2. 獲取該元素後的所有內容。
  3. 制定一套這些元素,因爲你顯然不想重複。

這看起來像:

set(the_list[the_list.index(the_element) + 1:]) 

現在,我已經想通了,你實際上問:

的過程是:

  1. 獲取相鄰元素的對,讓最後一個元素成爲paire d與None
  2. 從第一個元素匹配的每一對中返回第二個元素的迭代。

這看起來像:

(x[1] for x in zip(the_list, the_list[1:] + [None]) if x[0] == the_element)