我有一个如下所示的示例文件:
@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 :(得分:2)
你不能只切片行列表吗?
lines = fp.readlines()
interesting_lines = lines[2::4]
编辑其他人质疑其工作原理:
"完整"切片语法分为三部分:start:end:step
start
是起始索引,默认为0。因此,对于4 * i + 2,当i == 0时,即索引#2。
end
是结束索引,默认为len(sequence)
。切片上升到但不包括最后一个索引。
step
是所选项目之间的增量,默认为1。通常,像3:7
这样的切片会返回元素3,4,5,6(和不 7)。但是,当您添加step
参数时,您可以执行类似"步骤4和#34;等操作。
执行"步骤4"意味着start+0, start+4, start+8, start+12, ...
这是OP想要的,只要正确选择start
参数。
答案 1 :(得分:0)
您可以执行以下操作之一:
从0开始xrange
,然后在辅助循环
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
答案 2 :(得分:0)
我不清楚你在这里尝试做什么 - 你实际上只是想从磁盘读取你想要的线路吗? (在这种情况下,您从一开始就出错了,因为up()
会读取整个文件。)或者您只是想过滤行列表来挑选出您想要的行?
我会假设后者。在这种情况下,最简单的方法是使用listcomp按索引过滤行。例如简单的事情:
public function up()
{
Schema::table('employees', function(Blueprint $table)
{
$table->dropColumn("address");
});
Schema::table('employees', function(Blueprint $table)
{
$table->string('address')->after("city");
});
}
然后你去了,你已经得到了你想要的线条,没有索引错误或任何愚蠢的东西。然后,您可以分离并简化其余代码以进行计数,只需对已过滤的列表进行操作。
(只是稍微编辑了第一个列表,使其更加惯用)
答案 3 :(得分:-2)
我已经对另一个问题给出了类似的答案:How would I do this in a file?
更好的解决方案(避免不必要的循环)
fp = open(fileName, "r")
def addToDict(letter):
someDict[letter] += 1;
[addToDict('V') for 'V' in str(a) for a in fp.readlines()[2::4]];
我试图让这个匿名函数没有成功,如果有人能做到这一点就会很棒。