简体   繁体   English

遍历字符串列表,直到string == newline

[英]Iterate over a list of strings until string == newline

I am trying to read selective information from a file. 我正在尝试从文件中读取选择性信息。 File structure is as follows : 文件结构如下:

Component1:
   Detail1
   Detail2
   Detail3

Component2:
   Detail1
   Detail2
   Detail3

Component3:
   Detail1
   Detail2
   Detail3

Component4:
   Detail1
   Detail2
   Detail3

File has limited no. 文件没有限制。 of lines and I am reading that file into a list of lines. 行,我正在将该文件读入行列表。

with open('/tmp/filename.txt', 'r') as openf:
            for line_no, line in enumerate(openf):
                file_lines_list.append(line)

I want to selectively read information of Component2 我想选择性地读取Component2的信息

So I wrote following code. 所以我写了下面的代码。

with open('/tmp/filename.txt', 'r') as f:
                for line_no, line in enumerate(f):
                    if "Component2" in line:
                       x = line_no
                       print(x)
                       for item in file_lines_list[x:]:
                           if item != "\n":   
                              tmp_file.write(item)
                           else:
                              break

But it's printing lines till end of list (of lines of file). 但这是打印行直到列表末尾(文件行)。 It's not breaking at 1st occurrence of newline which should be ideally line just before Component3 . 它不会在第一次出现换行符时中断,理想情况下应该是在Component3之前的行。 (There are no newlines between details of components) Can someone point out what am I doing wrong here? (组件详细信息之间没有换行符)有人可以指出我在做什么错吗?

Using str.startswith() along with a boolean flag: 使用str.startswith()和一个布尔标志:

list.txt : list.txt

Component1:
   C1_Detail1
   C1_Detail2
   C1_Detail3

Component2:
   C2_Detail1
   C2_Detail2
   C2_Detail3

Component3:
   C3_Detail1
   C3_Detail2
   C3_Detail3

Component4:
   C4_Detail1
   C4_Detail2
   C4_Detail3

Hence : 因此

with open('list.txt', 'r') as f:
    content = f.readlines()

# you may also want to remove empty lines
content = [l.strip() for l in content if l.strip()]
bFlag = False
for line in content:
    if line.startswith('Component2'):
        bFlag = not bFlag
    if bFlag:
        if 'Component3' in line:
            break
        else:
            print(line)

OUTPUT : 输出

Component2:
C2_Detail1
C2_Detail2
C2_Detail3

For me this task is simpler if you load text as whole (using read ) rather than as list of lines (using readlines ). 对我来说,如果您整体加载文本(使用read )而不是行列表(使用readlines ),则此任务会更简单。 I would do it following way: 我将按照以下方式进行操作:

with open('input_file.txt','r') as openf:
    data = openf.read()
components = data.split('\n\n')
components = [i for i in components if i.startswith('Component2')]
print(len(components)) #prints 1 as expected
with open('out_file.txt','w') as f:
    f.write(components[0])

I assume that there is exactly 1 component fullfilling condition. 我假设组件完全满足1个条件。 This solution make described task done, however might be not best if you would need that lines list anyway, so feel free to choose solution best suited for your use case needs. 该解决方案使描述的任务完成,但是如果您仍然需要该行列表,则可能不是最好的选择,因此可以随时选择最适合您的用例需求的解决方案。

with open('file') as file:
    # remove empty lines
    lines = [line for line in file.readlines() if line]

    # holds all our components
    components = {}
    # holds the last component
    comp_name = None
    for line in lines:
        if not line.startswith('   '):
            # remove : from the end for easy reference
            comp_name = line[:-1]
            # add new Component our map
            components[comp_name] = []
        else:
            # add detail to component that already exists
            components[comp_name].append(line.strip())

    # now we just find our component
    print(components['Component2'])

This prints: 打印:

['Detail1', 'Detail2', 'Detail3']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM