2016-05-24 57 views
0

我有一個列表中的項目序列。我想識別相同元素的運行並打印它們的起始和結束位置。例如,對於:確定重複列表項的運行

content=[c,c,c,c,f,f,f,f,c,c,b,b,b,b...] 

我所要的輸出如:

1-4 c 
5-8 f 
9-10 c 

等等等等。這是我到目前爲止有:

x=len(content)-1 
i=0 
y=0 
z=0 
for i in range(0,x): 
    if(content[i]==content[i+1]): 
    y=y+1 
    z=i-1 
    else: 
    print y 
    print content[z] 
+2

你能證明你在使用'if'並試圖'else'來解決這個問題? – TigerhawkT3

+0

您能否提供您嘗試過的具體例子? – glls

+0

X = LEN(內容) I = 0 對於i在(O,X): 如果(內容[I] ==內容[I + 1]): 否則: 打印i + 1的 – Arushi

回答

1

首先是不是你的ifelse,而是如何你循環。您似乎錯過了對range的調用,並且只有調用的參數。嘗試:

for i in range(0, x): 

ifelse塊現在將達成,而你只需要調整他們跟蹤你所關心的值。如果你想要開始和連續運行項目,你實際上不需要這兩個部分。試試這個:

run_start = 0 
for i in range(len(content)-1): 
    if content[i] != content[i+1]: # only one branch needed, nothing to do when items are == 
     print "{}-{} {}".format(run_start+1, i+1, content[i]) 
     run_start = i+1 
print "{}-{} {}".format(run_start+1, len(content), content[-1]) # extra code for the last run 

這將打印出像3-3範圍,如果只有一個在運行項目。如果你不想要,你可能需要添加另一個if語句來檢查irun_start是否不相等(並且打印其他內容,或者如果它們是跳過該內容)。

我發現在可能的情況下使用有意義的變量名是非常有用的。在這種情況下,我使用run_start而不是yx

+0

我編輯了這些東西。但我仍然無法使用它。我覺得這個邏輯有問題。 – Arushi

1

Blckknght的解決方案非常棒。我自己的版本更加冗長,以幫助您理解整個流程背後的邏輯。你需要做的是迭代列表中的每個元素並將其存儲在current中,並將其與上一次迭代中的last(最後一個已知對象)進行比較。如果它們是相同的,那麼你增加range_end索引。如果它們是不同的,那麼就意味着一個新的範圍開始,所以你必須做幾件事情:

  • 打印到目前爲止所學的知識,儘可能range_beginrange_endcurrent元素。
  • current元素last,因爲它是新的序列
  • 設置,使整個過程的工作,你需要在兩個範圍指標range_beginrange_end到當前i

的第一要素在循環到content列表的第一個元素之前初始化last

另外,由於索引i是從0開始的,所以當我們打印range_beginrange_end時,我們只需增加1。

content=['c','c','c','c','f','f','f','f','c','c','b','b','b','b'] 
range_begin=0 
range_end=0 
last=content[0] # store the first element as the last known 
for i in range(0, len(content)): 
    current = content[i] # get the element from the list 
    if last != current: # compare to the last known, if different 
    print "{}-{} {}".format(range_begin+1, range_end+1, last) # print 
    last = current  # store the current as last known 
    range_begin = i  # reset the ranges to the current index 
    range_end = i 
    else: 
    range_end = i  # if they are the same, just extend the range_end 

檢查也於: https://eval.in/575899

1

你正在試圖解決一個不平凡的(如果還相當簡單)的問題,我建議你從標準庫的幫助。 itertools模塊提供的功能幾乎可以滿足您的需求。定元件 X 的序列,..., XÑ它會產生你的關鍵ķ和一個非空的懶惰序列的雙(ķ)元件 g,其比較等於 k。 (您可以通過應用list轉換成一個普通的列表)。

讓我們嘗試一下:

from itertools import groupby 
items = "ccccffffccbbbb" 
for (k, g) in groupby(items): 
    print k, list(g) 

輸出:

c ['c', 'c', 'c', 'c'] 
f ['f', 'f', 'f', 'f'] 
c ['c', 'c'] 
b ['b', 'b', 'b', 'b'] 

這看起來已經相當有用的,但我們必須從相等項目的列表中計算開始和結束索引。幸運的是,我們知道第一組的開始索引 - 它是1.如果我們知道任何組的開始索引,我們也知道它的結束索引,它是開始索引加上組的長度減1.開始索引的下一組將是當前組的開始索引加上當前組的長度。

這是我們所需要的:

from itertools import groupby 
items = "ccccffffccbbbb" 
offset = 1 
for (k, g) in groupby(items): 
    length = len(list(g)) # simple and does the job but not as efficient as it could be 
    print '{}-{} {}'.format(offset, offset + length - 1, k) 
    offset += length 

輸出:

1-4 c 
5-8 f 
9-10 c 
11-14 b