2015-12-21 93 views
3

我正在读取数据文件。行与连续的号码(步骤)开始,有时在每行之间有一个0计算列表中其他元素之间特定元素的数量

E.g:

1 
0 
2 
0 
3 
4 
5 
0 
0 
0 
6 
0 

如何创建计数在每个步骤之间0的个数名单。

我想是这样的列表:

finalList = [1,1,0,0,3,1] 

其表示每个步骤包含0的个数,即:步骤1具有1个零,步骤2具有1个零,步骤3具有0零,步骤4有0个零,步骤5有3个零,步骤6有1个零。

+2

你能展示你的尝试吗? –

回答

3

如果您的数据文件看起来与您所描述的完全一样(例如,除了增加步数和零的数量外没有其他数字),下面的代码应该可以工作。

cur = 0 
res = [] 
with open("file.txt") as f: 
    for line in f: 
     if line.strip() == '0': 
      cur += 1 
     else: 
      res.append(cur) 
      cur = 0 
+1

你应该强制转换为int或者与char'“0”进行比较,我怀疑它不会起作用。 – Delgan

+1

谢谢,@Delgan,你是对的。我确定了答案。 –

+4

这在至少三种方式中不起作用:您正试图“剥离”文件;你将结果与一个整数进行比较;并且你使用'append'作为一个函数。而那之前我甚至可以运行它来查看答案是否正确! – DSM

1

我想出了这一点:

finalList = [] 
count = 0 
step = None 

for e in [1, 0, 2, 0, 3, 4, 5, 0, 0, 0, 6, 0]: 
    if e > 0: 
     if step: 
     finalList.append(count) 
     step = e 
     count = 0 
    else: 
     count += 1 
if step: 
    finalList.append(count) 
+0

谢谢你的帮助!此代码已经过测试,适用于我的情况。 –

2
a = [1,0,2,0,3,4,5,0,0,0,6,0] 
finalList = [] 
count = 0 
for i in xrange(len(a)): 
    if i == 0 : continue 
    if a[i] == 0 : 
     count += 1 
    else : 
     finalList.append(count) 
     count = 0 
finalList.append(count) 
+1

谢谢@Pulkit。这有帮助:) –

0

替代解决方案

# temp list (copy of l with last element if doesn't exist) 
_l = l if l[-1] > 0 else l + [max(l) + 1] 
# _l.index(i) - _l.index(i - 1) - 1 = distance between elements 
[_l.index(i) - _l.index(i - 1) - 1 for i in range(2, max(_l) + 1)] 
+0

谢谢@Tomasz。短而甜蜜:) –

2

使用Python的可能过于聪明的解决方案包括电池:

from itertools import chain, groupby 

with open("file.txt") as f: 
    # Add extra zeroes after non-zero values so we see a group when no padding exists 
    extrazeroes = chain.from_iterable((x, 0) if x else (x,) for x in map(int, f)) 

    # Count elements in group and subtract 1 if not first group to account for padding 
    # The filter condition means we drop non-zero values cheaply 
    zerocounts = [sum(1 for _ in g) - bool(gnum) for gnum, (k, g) in enumerate(groupby(extrazeroes)) if k == 0] 

    # If leading zeroes (before first non-zero line) can't happen, simplify to: 
    zerocounts = [sum(1 for _ in g) - 1 for k, g in groupby(extrazeroes) if k == 0] 

是的,这有点复杂(如果你不关心在两个非零值之间没有间隔的情况下包含零),但它很简洁,应该非常快。如果你能在你的计数省略0 S,这将简化到更清洁:

with open("file.txt") as f: 
    zerocounts = [sum(1 for _ in g) for k, g in groupby(map(int, f)) if k == 0] 

为了记录在案,我会使用后者,如果它满足的要求。前者应该不会进入生产代码。 :-)

请注意,根据您的使用情况,使用groupby可能是您更广泛的问题的好主意;在评论中,你提到你正在存储文件中的所有行(使用f = f.readlines()),这意味着你将访问它们,可能基于存储在zerocounts中的值。如果您有一些特定的需求需要根据以下零的数量来处理每个“步骤”,则上面代码的修改可能会为通过懒散分组和处理篡改文件节省内存开销。

注:为了避免啜整个文件到内存中,在Python 2,你要添加from future_builtins import map所以map是一个懒惰的发电机的功能就像是在PY3,而不是加载整个文件,并转换所有它的前面是int。如果您不想跺脚map,则导入并使用itertools.imap而不是map转换为int转换可以实现相同的目标。

+1

这是一个非常好的方法。我可以用这个......谢谢! –

相关问题