2017-10-19 108 views
0

我想在列表上運行此循環基本上它會搜索我的範圍內的一個數字,直到它找到它在下面的迭代中搜索下一個數字,而是它開始再次如何打破並從我開始在嵌套循環中結束

這是我的代碼

z = [30,84,126,135,137,179,242,342,426] 
c=[] 
for m in z: 
    for i in range(1,1002, 7): 
     if m in range(i, i+7): 
      c.append(m%7) 
      break 
     elif m not in range(i, i+7): 
      c.append(0) 
print len(c) # outputs 246 

但LEN(C)應該等於143,我該如何解決這個問題?

+0

那你爲什麼'break'? –

+0

,因爲它繼續搜索以下範圍中的數字,即使它找到它並且在這種情況下len(c)變成1287 –

+0

最簡單的方法是將inner for loop提取到方法。那麼這些循環不會嵌套,並且不會對你打破哪個循環造成困惑 – MatthewMartin

回答

1

generator似乎回答這個問題,有一個編程問題的一個更好的工具:itertools.groupby

from itertools import groupby 


z = [1,2,3, 30,84,126,135,136,137,140,141,179,242,342,426] 

g = dict([[k, [*g]] for k, g in groupby(z, key=lambda x: (x-1)//7)]) 

d = [((tuple(g[i]) if len(g[i]) > 1 else g[i][0]) if (i in g) else 0) 
    for i in range(0, 143)] 

撞上了我的第一個答案的代碼:(不要使用相同的z,它已經改變)

c == d 
Out[278]: True 

看到如何很好地匹配itertools.groupby是看字典包裹GROUPBY結果:

g 
Out[279]: 
{0: [1, 2, 3], 
4: [30], 
11: [84], 
17: [126], 
19: [135, 136, 137, 140], 
20: [141], 
25: [179], 
34: [242], 
48: [342], 
60: [426]} 

(上述工程在3.6中,[*g]dictionary key測試(i in g) 2.7可能會有所不同)

+0

感謝這確實是輝煌的,更高效的內部 –

1

我想我想通了你想做什麼,最好的選擇就是改變你的搜索範圍。

z = [30,84,126,135,137,179,242,342,426] 
c=[] # initialize results array 
i = 1 # initialize i 
for m in z: # for each item in list 
    while 1: # perform this action until loop breaks 
     if m in range(i, i+7): #if m is in range 
      c.append(m%7) 
      break #break the while loop, moving on to the next item 
     elif m not in range(i, i+7): 
      c.append(0) 
      i = i+7 #increment the search range, but do not break the loop 

#Display results 
print len(c) 
print c 

因此,在你原來的代碼,你的陣列z在重置搜索範圍i每個元素。這就是爲什麼你的len(c)值比預期的要高得多。在我的代碼中,當我遍歷數組數組時,我只從1次迭代到1002次。

請讓我知道如果這不能解決您的問題,我能夠匹配您描述的功能,但不是len(c)的預期輸出。如果你想要得到的預期值,您可以更改代碼以匹配這樣的:

z = [30,84,126,135,137,179,242,342,426] 
c=[] # initialize results array 
i = 1 # initialize i 
for m in z: # for each item in list 
    while i<1002: # perform this action until loop breaks 
     if m in range(i, i+7): #if m is in range 
      c.append(m%7) 
      i = i+7 
      break # break the while loop, moving on to the next item 
     elif m in range(i-7, i): 
      break 
     else: 
      c.append(0) 
      i = i+7 # increment the search range, but do not break the loop 

while i<1002: # finish iterating i all the way up to 1002 
    c.append(0) 
    i = i+7 


#Display results 
print len(c) 
print c 

它獲取的143

+0

感謝了很多,但不是我想要的輸出LEN(三)應該等於143又似乎是壞了零的列表中的任何想法還有什麼我可以嘗試多少? –

+0

第一個解決方案是更好,但我怎麼讓它持續到1002這是我的範圍 –

+0

的一端固定我的代碼一路得到我到1002 – ividito

1

一個len(c)也許你想要的是一個generatorhttps://docs.python.org/2/howto/functional.html#generator-expressions-and-list-comprehensions

z = [30,84,126,135,136,137,179,242,342,426] 
c = [] 


def counter(maximum, inc): # resetable generator from doc example 
    i = 1 
    while i < maximum: 
     val = (yield i) 
     # If value provided, change counter 
     if val is not None: 
      i = val 
     else: 
      i += inc 


ig = counter(1002, 7) 

for m in z: 
    for i in ig: 
     # catch multiple nums in same range 
     if m < i: 
      clast = c.pop() 
      # inline if-else inside append converts int to tuple to add m to 
      c.append((clast if type(clast) == tuple else (clast,)) + (m,)) 
      # reset ig count 
      ig.send(i - 7) 
      break 

     if i <= m < i+7: 
      c.append(m) 
      break 
     else: 
      c.append(0) 
# exhaust ig if you really want full count = 143 
for i in ig: 
    c.append(0) 

print(len(c)) 

在相同的時間間隔內添加了捕捉數量,需要可復位發生器

修正了我所知道的最後2個問題: 使得現在在一個範圍內的多個NUMS平坦的元組 計數正確地重置IG到I - 7

+0

輸出錯了,它135後附加沒有數字,所以列表填充後零,也許是因爲137是在同一範圍內與135我該如何處理,也許把它落在同一範圍內的元組的數量名單 –

+0

,是完美非常感謝 –