【问题标题】:Counting jump(no of lines) between first two 'String' occurrences in a file计算文件中前两个“字符串”出现之间的跳转(行数)
【发布时间】:2012-12-03 09:54:22
【问题描述】:

我有一个巨大的数据文件,其中包含在定义的行数后重复的特定字符串。

计算前两个“排名”出现之间的跳跃。例如文件如下所示:

  1 5 6 8 Rank                     line-start
  2 4 8 5
  7 5 8 6
  5 4 6 4
  1 5 7 4 Rank                     line-end  
  4 8 6 4
  2 4 8 5
  3 6 8 9
  5 4 6 4 Rank

您会注意到字符串 Rank 每隔 3 行重复一次。因此,对于上面的示例,块中的行数为 4。我的问题是如何使用 python readline() 获取行数。

我目前关注这个:

data = open(filename).readlines()
count = 0
for j in range(len(data)):
  if(data[j].find('Rank') != -1): 
    if count == 0: line1 = j
    count = count +1 
  if(count == 2):
    no_of_lines = j - line1
    break

欢迎提出任何改进或建议。

【问题讨论】:

  • 您要计算文件中的总行数,还是只计算其中包含单词 rank 的行数?
  • @InbarRose 想计算包含字符串 Rank 的行之间的行数。
  • 如果每个块的行数相同,则只计算第一个块。
  • 谢谢@fanlix 是的,这正是我所需要的。您可以注意到我的代码中的 break 语句,它在找到第一个块中的行数后停止循环
  • 我不能用不到 5 行代码完成这项工作。等待一些专业......

标签: python string readline readfile


【解决方案1】:

当一个简单的生成器表达式用Rank 计算行数就足够时,不要使用.readlines()

count = sum(1 for l in open(filename) if 'Rank' not in l)

'Rank' not in l 足以测试字符串 'Rank' 是否不存在于字符串中。循环打开的文件就是循环所有的行。 sum() 函数会将所有1s 相加,这些1s 是为每行不包含Rank 生成的,为您提供其中不包含Rank 的行数。

如果您需要计算从RankRank 的行数,您需要一点itertools.takewhile 魔术:

import itertools
with open(filename) as f:
    # skip until we reach `Rank`:
    itertools.takewhile(lambda l: 'Rank' not in l, f)
    # takewhile will have read a line with `Rank` now
    # count the lines *without* `Rank` between them
    count = sum(1 for l in itertools.takewhile(lambda l: 'Rank' not in l, f)
    count += 1  # we skipped at least one `Rank` line.

【讨论】:

  • 我想计算有Rank的行之间的行
  • @Alaissham:然后添加了简单的“不”。 :-)
  • 问题是,我想包含具有字符串 'Rank' 的行并计算后续行,直到该行到达并找到具有字符串 Rank 的行(此行不包括在内)。
【解决方案2】:

计算前两个 'Rank' 出现之间的跳转:

def find_jumps(filename):
    first = True
    count = 0
    with open(filename) as f:
        for line in f:
            if 'Rank' in line:
                if first:
                    count = 0 
                    #set this to 1 if you want to include one of the 'Rank' lines.
                    first = False                    
                else:
                    return count
            else:
                count += 1 

【讨论】:

    【解决方案3】:

    我假设您想查找块中的行数,其中每个块以包含“排名”的行开头,例如,您的样本中有 3 个块:第一个有 4 行,第二个有 4 行,第三个有1 行:

    from itertools import groupby
    
    def block_start(line, start=[None]):
        if 'Rank' in line:
           start[0] = not start[0]
        return start[0]
    
    with open(filename) as file:
         block_sizes = [sum(1 for line in block) # find number of lines in a block
                        for _, block in groupby(file, key=block_start)] # group
    print(block_sizes)
    # -> [4, 4, 1]
    

    如果所有块的行数相同,或者您只想查找以'Rank'开头的第一个块中的行数:

    count = None
    with open(filename) as file:
         for line in file:
             if 'Rank' in line:
                 if count is None: # found the start of the 1st block
                    count = 1
                 else: # found the start of the 2nd block
                    break
             elif count is not None: # inside the 1st block
                 count += 1
    print(count) # -> 4
    

    【讨论】:

    • 对不起,误导的例子,所有的块都有相同的行数,我没有完全输入。找到第一个块本身的行数就足够了
    • 是不是和我的代码逻辑类似,除了使用readlines。我使用 readlines 是因为我对数据进行了一些后处​​理。
    【解决方案4】:

    7行代码:

    count = 0
    for line in open("yourfile.txt"):
        if "Rank" in line: 
            count += 1
            if count > 1: break 
        elif count > 0: count += 1
    print count
    

    【讨论】:

    • 再次抱歉这个误导性的例子,我在文件的开头和结尾有一些更不相关的行。
    猜你喜欢
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    相关资源
    最近更新 更多