Python 按顺序对列表中的元素进行分组
我是python新手。有一项复杂的任务要做 我有一个文本文件,其中包含由注释和命令分隔的部分。文件中有多个部分。我想提取与它自己的部分相关的命令,并从中创建一个列表 示例:Python 按顺序对列表中的元素进行分组,python,list,grouping,Python,List,Grouping,我是python新手。有一项复杂的任务要做 我有一个文本文件,其中包含由注释和命令分隔的部分。文件中有多个部分。我想提取与它自己的部分相关的命令,并从中创建一个列表 示例: test.txt #section 1 ls -1 sudo apt-get install vim #section 2 sudo apt-get install ruby 输出: list1 = ['ls -1','sudo apt-get install vim'] list2 = ['sudo apt-get
test.txt
#section 1
ls -1
sudo apt-get install vim
#section 2
sudo apt-get install ruby
输出:
list1 = ['ls -1','sudo apt-get install vim']
list2 = ['sudo apt-get install ruby']
您的问题是一个简单的分组练习,它可以通过跟踪一个节的开始来实现,以指示后续行应该附加到一个新列表中 实施
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:]
假设您的文件包含
test.txt
#section 1
ls -1
sudo apt-get install vim
#section 2
ls -lrt
sudo apt-get install ruby
输出
[['ls -1', 'sudo apt-get install vim'], ['ls -lrt', 'sudo apt-get install ruby']]
使用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']
对于python2,使用itertools.imap
和itertools.ifilter
您可以创建具有列表理解的列表列表:
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']]
如果您希望存储,以便可以按名称访问,请使用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']}
您可以创建一个最初为空的节列表。每次找到以
#
开头的行时,都会附加一个子列表。否则,如果到目前为止遇到一个节,并且该行不是空的,则将该行添加到最后插入的节的子列表中
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)
结果:
[['ls -1', 'sudo apt-get install vim'], ['sudo apt-get install ruby']]
嗨,欢迎来到StackOverflow!你还没有问过一个问题,那么你在努力完成任务的哪一部分呢?最好是展示您迄今为止编写的代码,并解释它如何没有达到您期望的效果。那么我们就有可能找出它的毛病了。谢谢蒂姆。这是以前的代码,我正在根据这里的人提供的输入修改它。def extract(self,outfile,mode):f=self中c的open(outfile,mode)。内容:如果不是c.startswith(“#”):commands=c.rstrip()#f.write(commands+'\n')self.clist.append(commands)f.close()我会纠正它…但即使你用一个衬垫…我认为它太大了,不能放在一个衬垫里line@JuniorCompressor,它符合pep8,并给出正确的答案,因此否决票仍然非常有趣。@JUnitorCompressor,您必须记住程序员是懒惰的;)