Reputation: 39
I am new to python. Got a complex task to work on.
I have a text file containing a sections separated by comments and commands are in between them. There are multiple sections in the files. I want to extract the commands related it's own section and create a list out of it.
Eample:
test.txt
#section 1
ls -1
sudo apt-get install vim
#section 2
sudo apt-get install ruby
output:
list1 = ['ls -1','sudo apt-get install vim']
list2 = ['sudo apt-get install ruby']
Upvotes: 2
Views: 94
Reputation: 180522
Use groupby:
from itertools import groupby
with open("test.txt") as f:
for k, v in groupby(map(str.strip, f), lambda x: not x.startswith("#")):
if k:
print(list(filter(None, v)))
['ls -1', 'sudo apt-get install vim']
['sudo apt-get install ruby']
For python2 use itertools.imap
and itertools.ifilter
You can create a list of lists with a list comprehension:
from itertools import groupby
with open("test.txt") as f:
out = [list(filter(None, v)) for k, v in groupby(map(str.strip, f), lambda x: not x.startswith("#")) if k]
print(out)
['ls -1', 'sudo apt-get install vim'], ['sudo apt-get install ruby']]
If you want then stored so you can access by name use a dict:
from itertools import groupby
from itertools import count
with open("test.txt") as f:
d = {}
cn = count(1)
for k, v in groupby(map(str.strip, f), lambda x: not x.startswith("#")):
if k:
d["list_{}".format(next(cn))] = list(filter(None, v))
print(d)
{'list_2': ['sudo apt-get install ruby'], 'list_1': ['ls -1', 'sudo apt-get install vim']}
Upvotes: 1
Reputation: 20025
You can create an initially empty list of sections. Every time you find a line that starts with #
you append a sublist. Otherwise, if we encountered a section so far and the line is not empty, we add the line to the last inserted sublist of sections
.
sections = []
with open("test.txt", "r") as f:
for line in map(str.strip, f):
if line.startswith('#'):
sections.append([])
elif sections and line:
sections[-1].append(line)
Result:
[['ls -1', 'sudo apt-get install vim'], ['sudo apt-get install ruby']]
Upvotes: 2
Reputation: 63777
Your problem is a simple grouping exercise, which can simply be achieved by keeping track of a section start for indicating that the subsequent lines should be appended to a new list
Implementation
output = [[]]
with open("test.txt") as fin:
#from itertools import imap
for line in map(str.strip, fin):
#for line in imap(str.strip, fin):
if line:
if line.startswith('#'):
output.append([])
continue
output[-1].append(line)
output = output[1:]
Assuming your file contains
test.txt
#section 1
ls -1
sudo apt-get install vim
#section 2
ls -lrt
sudo apt-get install ruby
output
[['ls -1', 'sudo apt-get install vim'], ['ls -lrt', 'sudo apt-get install ruby']]
Upvotes: 2