在 Python 的嵌套 for 循环中使用 Continue 语句
Posted
技术标签:
【中文标题】在 Python 的嵌套 for 循环中使用 Continue 语句【英文标题】:Using Continue Statement in nested for loop in Python 【发布时间】:2012-07-23 01:07:43 【问题描述】:您好,我有一个从两个文件中读取数据的函数。我想要发生的是外部循环开始读取第一个文件,如果第一个文件中的 lum 大于定义值(LC),则循环跳到下一次迭代。如果不是,代码将移至 如果 idc 和 id 相同,则读取 hlist 并构建 x、y、z 列表的内部循环。如果 idc 和 id 不是相同的值,它会跳到内部循环的下一次迭代。当我打印测试语句时,内部循环似乎没有迭代,我不清楚为什么。我会很感激任何帮助
代码
def read_file(F): #Function that reads data froma file #and extracts specific data columns
X_pos = []
Y_pos = [] # Creats Data Lists
Z_pos = []
Idh = []
Id = []
LC = float(sys.argv[1])
N = 11#912639 # number of lines to be read
Nl = 11#896030
fl = open(Fl) #opens catalog file
fl.readline()
nlines_catalog = islice(fl, Nl)
f = open(F) #Opens hlist file
f.readline() # Strips Header
nlines_hlist = islice(f, N) #slices file to only read N lines
for linel in nlines_catalog:
if linel != '':
linel = linel.strip()
linel = linel.replace('\t', '')
columnsl = linel.split()
lum = float(columnsl[1])
id_catalog = int(columnsl[0])
if lum >= LC:
continue
print("lum1 =", lum)
#Id.append(idc)
print("id_catalog=", id_catalog)
for line in nlines_hlist:
if line != '':
line = line.strip()
line = line.replace('\t', ' ')
columns = line.split()
id_hlist = int(columns[1])
#Idh.append(id)
if id_hlist != id_ccatalog:
continue
print('idc =', idc, 'id =', id)
x = columns[17]
y = columns[18]
z = columns[19]
X_pos.append(x)
Y_pos.append(y) #appends data in list
Z_pos.append(z)
print(X)
X = [float(p) for p in X_pos]
Y = [float(p) for p in Y_pos]
Z = [float(p) for p in Z_pos]
Xa = numpy.array(X, dtype=float)
Ya = numpy.array(Y, dtype=float)
Za = numpy.array(Z, dtype=float)
return(Xa, Ya, Za)
编辑
对内部循环的更改使其可以重置并现在可以工作。
if id_catalog == id_halo:
print('id_catalog =',id_catalog,'id_halo =',id_halo)
x = columns[17] # assigns variable to columns
y = columns[18]
z = columns[19]
#vx = columns[]
#vy = columns[]
#vz = columns[]
X_pos.append(x)
Y_pos.append(y) #appends data in list
Z_pos.append(z)
break
编辑 我无法从打印语句中复制我的原始输出,并进行了编辑以反映这一事实
VirtualBox:~$ python /home/Astrophysics/Count_FixedLoop.py -21.5 125
('lum1 =', -21.78545)
('idc=', 2701276876L)
('idc =', 2701276876L, 'id =', 2701276876L)
('lum1 =', -21.69835)
('idc=', 2699751347L)
('lum1 =', -21.69942)
('idc=', 2699724518L)
('lum1 =', -21.74543)
('idc=', 2699724331L)
('lum1 =', -21.60912)
('idc=', 2699724726L)
('lum1 =', -21.53862)
('idc=', 2699725014L)
('lum1 =', -21.53155)
('idc=', 2701277269L)
['34.57223']
这是我期望的输出
('lum1 =', -21.78545)
('idc=', 2701276876L)
('idc =', 2701276876L, 'id =', 2701276876L)
('lum1 =', -21.69835)
('idc=', 2699751347L)
('idc =', 2699751347L, 'id =', 2699751347L)
('lum1 =', -21.69942)
('idc=', 2699724518L)
('idc =', 2699724518L, 'id =', 2699724518L)
('lum1 =', -21.74543)
('idc=', 2699724331L)
('idc =', 2699724331L, 'id =', 2699724331L)
('lum1 =', -21.60912)
('idc=', 2699724726L)
('idc =', 2699724726L, 'id =', 2699724726L)
('lum1 =', -21.53862)
('idc=', 2699725014L)
('idc =', 2699725014L, 'id =', 2699725014L)
('lum1 =', -21.53155)
('idc=', 2701277269L)
编辑
FL 文件的几行示例,其中 idc 编号为 column[0],lum 值为 column[1]。我在第一个循环中将满足条件的 idc 值加粗。
Format: ID, scatter = 0 0.05 0.1 0.13 0.15 0.16 0.18 0.2 0.25 0.3
**2701276876 -21.78545** -21.73791 -21.68872 -21.11125 -20.88102 -22.04709 -21.41715 -20.56944 -20.36757 -19.69895
**2699751347 -21.69835** -21.67935 -21.92425 -21.03465 -21.56561 -21.42124 -21.72893 -20.78131 -20.76342 -20.34830
**2699724518 -21.69942** -21.58352 -21.71149 -21.16240 -21.18507 -22.00277 -21.81500 -20.36141 -20.78227 -20.65697
编辑
F文件的样本行,其id和对应位置与第一个文件匹配
#Scale(0) Id(1) Desc_scale(2) Descid(3) Num_prog(4) Pid(5) Upid(6) Desc_pid(7) Phantom(8) Mvir(9) Orig_Mvir(10) Rvir(11) Rs(12) Vrms(13) Mmp(14) Last_mm(15) Vmax(16) X(17) Y(18) Z(19)
0.9523 **2701276876** 0.9583 2714557311 1 -1 -1 -1 0 3.56533e+13 3.56100e+13 695.459000 80.562000 548.820000 1 0.3603 561.490000 **34.57223 140.20813 130.81985** -110.000 323.430 -123.520 3.56533e+13 3.56533e+13 561.490000 599.410000 7.539e+14 -3.799e+12 -1.992e+14 0.10259
0.9523 **2699751347** 0.9583 2713034575 4 -1 -1 -1 0 3.36604e+13 3.31300e+13 678.981000 111.199000 500.400000 1 0.8083 514.010000 **28.70439 138.70247 138.52176** -215.310 252.520 -120.970 3.36604e+13 3.36604e+13 514.010000 599.250000 5.516e+14 1.044e+14 6.133e+14 0.10973
0.9523 **2699724518** 0.9583 2713007786 1 -1 -1 -1 0 2.98000e+13 2.97500e+13 654.997000 87.324000 457.460000 1 0.4863 514.660000 **8.01627 135.31783 123.13322** -178.990 558.900 1.250 2.98000e+13 2.98000e+13 514.660000 514.660000 8.529e+14 2.711e+14 -3.624e+14 0.15137
我期望的是,当两个文件中的 id 匹配时,第二个循环将附加 X、Y 和 Z 位置列表。所以在这个例子中打印列表会给
X = [34.57223,28.70439,8.01627]
Y = [140.20813,138.70247,135.31783]
Z = [130.81985,138.52176,123.13322]
【问题讨论】:
我们能看到 Count_FixedLoop.py 的代码吗?或者至少是调用 read_file 的部分? 这个代码示例有点难以理解。如果您显示输入文件中的一些行并告诉我们您想要完成什么,也许我们可以提供更好的帮助。 如前所述,查看数据文件有助于理解您的意图,但粗略检查:检查这些循环中所有语句的缩进级别。看来,如果有一个空的linel
你仍然执行内部循环 - 这是需要的吗?看起来您还将尝试从内部循环中的空 line
提取数据,因为您没有在 if line != '':
之后缩进所有其余语句
您确定输出是针对该代码的吗?我看不出在您提供的代码中会打印什么 idc= (而不是 'idc =')。一般来说,对于这样的问题,找到一个最小的测试用例可能会有所帮助(catb.org/~esr/faqs/smart-questions.html#code 提供了一些关于构建此类东西的建议)。在您的具体情况下,我会仔细查看您的 F 文件:它有多少条目?它们是否像您需要的那样在空间上分开?在找到与 F 的第二行匹配的 idc 之前,您必须经过 Fl 多远?但是构建一个最小的测试用例是要走的路。
...其他人都错过了islice()
的使用吗?
【参考方案1】:
您似乎期望nlines
表现得像一个列表。然而,它是一个iterator,正如 Ignacio 上面指出的那样,它将被消耗一次。换句话说,内部循环不会在随后的外部循环执行中“重置”到第一行/索引。
考虑以下对您正在做的事情的模拟(我认为)。这里有两个数据文件:
数据1:
file 1: one
file 1: two
file 1: three
file 1: four
file 1: five
数据2:
file 2: one
file 2: two
file 2: three
file 2: four
file 2: five
file 2: six
运行这个:
from itertools import islice
f1 = open ("Data1")
f2 = open ("Data2")
iterator1 = islice (f1, 3)
iterator2 = islice (f2, 3)
for line1 in iterator1:
print line1
for line2 in iterator2:
print line2
结果:
file 1: one
file 2: one
file 2: two
file 2: three
file 1: two
file 1: three
而人们可能错误地认为 data2
的前 3 行中的每一行都将打印 3 行 data1
的内容。
因此,内部循环的第一次执行完全消耗 iterator2
。在您自己的代码中,当 id == idc
时没有内部循环中断 - 换句话说,您在内部循环第一次执行时完全消耗了 interator nlines
。
另请参阅Python: itertools.islice not working in a loop 以获取另一个示例。
一个解决方案可能是在id == idc
时中断内部循环,但这将假设(我认为)您的第二个文件中的索引排序。您可以考虑实际使用内部循环列表,尽管考虑到您的实际(非测试)数据的大小,这似乎是内存密集型的。您显然可以重新读取第二个文件,尽管性能会受到影响。
【讨论】:
Keith 你对我对 nlines 行为的误解是正确的。我确实假设每次执行外循环时内循环都会重置。 我按照你的建议做了,改变了继续中断,现在它可以完美地工作了,非常感谢! 如果其他人有类似的问题,我也已经修改了问题 Keith,我的理解是正确的,如果我使用nlines_hlist = f:
qnd 而不是 nlines_hlist = islice(f, N):
,那么每次执行外循环后内循环都会重置?
没有。 f
是一个file object, which serves in effect as its own iterator(即它有一个.next()
方法)。我认为您可以在内部循环开始之前立即使用f.seek(0); f.readline()
之类的东西“重置”,这可以重写for line in f:
这基本上就是我说您可以重新读取第二个文件时的意思。 .您也可以反复打开和关闭它。以上是关于在 Python 的嵌套 for 循环中使用 Continue 语句的主要内容,如果未能解决你的问题,请参考以下文章
python 在itertools中使用product方法来避免嵌套for循环