我已经编写了一些代码,并试图掌握列表推导的概念,我试图将一些代码转换为列表推导。
我有一个嵌套的for循环:
with (Input) as searchfile:
for line in searchfile:
if '*' in line:
ID = line[2:13]
IDstr = ID.strip()
print IDstr
hit = line
for i, x in enumerate(hit):
if x=='*':
position.append(i)
print position
我已将代码的第一部分变为列表理解:
ID = [line[2:13].strip() for line in Input if '*' in line]
print ID
这很好用。我试图做下一个,但它没有按预期工作。如何在彼此之后进行多次列表推导。如果它是第一个列表理解,下面的“命中= ...” - 部分工作正常,但如果是第二个则不行。与上述相同 - 它似乎只是工作,如果它是第一个。这是为什么?
Hit = [line for line in Input if '*' in line]
print Hit
Positions = [(i, x) for i, x in enumerate(Hit) if x == '*']
print Positions
答案 0 :(得分:2)
它似乎只是工作,如果它是第一个。这是为什么?
这是因为file
对象 - 在你的情况下是input
- 是迭代器,即一旦你迭代它们就会耗尽它们。在for循环中,这不是问题,因为您只为ID
和position
迭代文件一次。如果你想使用这样的两个列表推导,你要么必须为第二个重新打开文件,要么将文件中的行读入列表,并在列表推导中使用该列表。
另请注意,您的positions
列表理解是错误的,因为它列举了Hit
列表,而不是列表中的每个元素,就像在你的循环。
您可以尝试这样(未经测试):
# first, get the lines with '*' just once, cached as a list
star_lines = [line for line in input if '*' in line]
# now get the IDs using those cached lines
ids = [line[2:13].strip() for line in star_lines]
# for the positions we need a nested list comprehension
positions = [i for line in star_lines for i, x in enumerate(line) if x == '*']
嵌套列表推导与这个嵌套循环相当:
positions = []
for line in star_lines:
for i, x in enumerate(line):
if x == '*':
posiitons.append(i)
基本上,你只是"压扁"那段代码并把东西放在前面。