2017-10-19 112 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

,是完美非常感谢 –