Я пытаюсь прочитать выборочную информацию из файла. Структура файла следующая:
Component1:
Detail1
Detail2
Detail3
Component2:
Detail1
Detail2
Detail3
Component3:
Detail1
Detail2
Detail3
Component4:
Detail1
Detail2
Detail3
Файл имеет ограниченный номер. строк, и я читаю этот файл в список строк.
with open('/tmp/filename.txt', 'r') as openf:
for line_no, line in enumerate(openf):
file_lines_list.append(line)
Я хочу выборочно прочитать информацию Компонент2
Поэтому я написал следующий код.
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
Но он печатает строки до конца списка (строк файла). Он не прерывается при первом появлении новой строки, которая в идеале должна быть строкой непосредственно перед Компонент3. (Нет новых строк между деталями компонентов) Может ли кто-нибудь указать, что я здесь делаю неправильно?
Использование str.startswith()
вместе с логическим флагом:
список.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
Следовательно:
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)
ВЫХОД:
Component2:
C2_Detail1
C2_Detail2
C2_Detail3
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'])
Это печатает:
['Detail1', 'Detail2', 'Detail3']
Не уверен, что чтение всех данных в память только для последующей фильтрации эффективно.
readlines
прочитает весь файл в память, несмотря ни на что. Если вы хотите быть эффективным, вы можете передать файл в потоковом режиме, но это не вопрос.
Для меня эта задача упрощается, если вы загружаете текст целиком (используя read
), а не как список строк (используя readlines
). Я бы сделал это следующим образом:
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])
Я предполагаю, что существует ровно 1 условие заполнения компонента. Это решение делает описанную задачу выполненной, однако может быть не лучшим, если вам все равно понадобится этот список строк, поэтому не стесняйтесь выбирать решение, наиболее подходящее для ваших потребностей.
Использовать
startswith()
и разбивать на пустую строку?