读取 Python 中的特定行序列
Read specific sequence of lines in Python
我有一个示例文件,如下所示:
@XXXXXXXXX
VXVXVXVXVX
+
ZZZZZZZZZZZ
@AAAAAA
YBYBYBYBYBYBYB
ZZZZZZZZZZZZ
...
我希望只读取落在索引 4i+2 上的行,其中 i 从 0 开始。所以我应该读取上面代码段中的 VXVXV (4*0+2 = 2)...
行和 YBYB...(4*1 +2 = 6)
行.我需要计算 'V's, 'X's,'Y's and 'B's
的数量并存储在预先存在的字典中。
fp = open(fileName, "r")
lines = fp.readlines()
for i in xrange(1, len(lines),4):
for c in str(lines(i)):
if c == 'V':
some_dict['V'] +=1
谁能解释一下我如何避免偏离索引并只读入行列表的 4*i+2 索引处的行?
您可以执行以下操作之一:
从 0 开始 xrange
,然后在二级循环中将 2 添加到 i
for i in xrange(0, len(lines), 4):
for c in str(lines(i+2))
if c == 'V':
some_dict['V'] += 1
从2开始xrange
,然后i
按照你原程序指定的方式访问
for i in xrange(2, len(lines), 4):
for c in str(lines(i))
if c == 'V':
some_dict['V'] += 1
我不太清楚你在这里想做什么——你真的只是想从磁盘中读取你想要的行吗? (在这种情况下,你从一开始就出错了,因为 readlines()
读取了整个文件。)或者你只是想过滤行列表以挑选出你想要的行?
我假设是后者。在这种情况下,最简单的做法就是使用 listcomp 按索引过滤行。例如像这样简单的东西:
indices = [x[0] * 4 + 2 for x in enumerate(lines)]
filtered_lines = [lines[i] for i in indices if len(lines) > i]
好了,您得到了您想要的行,没有索引错误或任何类似的愚蠢行为。然后你就可以把剩下的代码分离出来简化做计数,只对过滤后的列表进行操作。
(只是稍微编辑了第一个列表组合,使其更加地道)
我已经对另一个问题给出了类似的答案:
更好的解决方案(避免不必要的 for 循环)是
fp = open(fileName, "r")
def addToDict(letter):
someDict[letter] += 1;
[addToDict('V') for 'V' in str(a) for a in fp.readlines()[2::4]];
我试着把它变成一个匿名函数,但没有成功,如果有人能做到那就太好了。
你不能只分割行列表吗?
lines = fp.readlines()
interesting_lines = lines[2::4]
为质疑其工作原理的其他人编辑:
"full" 切片语法由三个部分组成:start:end:step
start
为起始索引,默认为0。因此,对于 4 * i + 2,当 i == 0 时,即索引 #2。
end
为结束索引,默认为len(sequence)
。切片最多 但不包括 最后一个索引。
step
是选中项之间的增量,默认为1。通常,像 3:7
这样的切片会 return 元素 3,4,5,6( 而不是 7)。但是当你添加一个step
参数时,你可以做类似"step by 4"的事情。
做 "step by 4" 意味着 start+0, start+4, start+8, start+12, ...
这是 OP 想要的,只要 start
参数选择正确。
我有一个示例文件,如下所示:
@XXXXXXXXX
VXVXVXVXVX
+
ZZZZZZZZZZZ
@AAAAAA
YBYBYBYBYBYBYB
ZZZZZZZZZZZZ
...
我希望只读取落在索引 4i+2 上的行,其中 i 从 0 开始。所以我应该读取上面代码段中的 VXVXV (4*0+2 = 2)...
行和 YBYB...(4*1 +2 = 6)
行.我需要计算 'V's, 'X's,'Y's and 'B's
的数量并存储在预先存在的字典中。
fp = open(fileName, "r")
lines = fp.readlines()
for i in xrange(1, len(lines),4):
for c in str(lines(i)):
if c == 'V':
some_dict['V'] +=1
谁能解释一下我如何避免偏离索引并只读入行列表的 4*i+2 索引处的行?
您可以执行以下操作之一:
从 0 开始 xrange
,然后在二级循环中将 2 添加到 i
for i in xrange(0, len(lines), 4):
for c in str(lines(i+2))
if c == 'V':
some_dict['V'] += 1
从2开始xrange
,然后i
按照你原程序指定的方式访问
for i in xrange(2, len(lines), 4):
for c in str(lines(i))
if c == 'V':
some_dict['V'] += 1
我不太清楚你在这里想做什么——你真的只是想从磁盘中读取你想要的行吗? (在这种情况下,你从一开始就出错了,因为 readlines()
读取了整个文件。)或者你只是想过滤行列表以挑选出你想要的行?
我假设是后者。在这种情况下,最简单的做法就是使用 listcomp 按索引过滤行。例如像这样简单的东西:
indices = [x[0] * 4 + 2 for x in enumerate(lines)]
filtered_lines = [lines[i] for i in indices if len(lines) > i]
好了,您得到了您想要的行,没有索引错误或任何类似的愚蠢行为。然后你就可以把剩下的代码分离出来简化做计数,只对过滤后的列表进行操作。
(只是稍微编辑了第一个列表组合,使其更加地道)
我已经对另一个问题给出了类似的答案:
更好的解决方案(避免不必要的 for 循环)是
fp = open(fileName, "r")
def addToDict(letter):
someDict[letter] += 1;
[addToDict('V') for 'V' in str(a) for a in fp.readlines()[2::4]];
我试着把它变成一个匿名函数,但没有成功,如果有人能做到那就太好了。
你不能只分割行列表吗?
lines = fp.readlines()
interesting_lines = lines[2::4]
为质疑其工作原理的其他人编辑:
"full" 切片语法由三个部分组成:start:end:step
start
为起始索引,默认为0。因此,对于 4 * i + 2,当 i == 0 时,即索引 #2。
end
为结束索引,默认为len(sequence)
。切片最多 但不包括 最后一个索引。
step
是选中项之间的增量,默认为1。通常,像 3:7
这样的切片会 return 元素 3,4,5,6( 而不是 7)。但是当你添加一个step
参数时,你可以做类似"step by 4"的事情。
做 "step by 4" 意味着 start+0, start+4, start+8, start+12, ...
这是 OP 想要的,只要 start
参数选择正确。