免责声明:我对python很新!
如果我想要一个文件的所有行,直到(编辑并包含)包含某些字符串stopterm
的行,是否有一种方法可以使用它的列表语法?我希望有类似的东西:
usefullines = [line for line in file until stopterm in line]
现在,我已经
了usefullines = []
for line in file:
usefullines.append(line)
if stopterm in line:
break
这不是世界末日,但由于Python语法的其余部分非常简单,我希望有一个思想 - > 1的Python行映射。
答案 0 :(得分:10)
from itertools import takewhile
usefullines = takewhile(lambda x: not re.search(stopterm, x), lines)
from itertools import takewhile
usefullines = takewhile(lambda x: stopterm not in x, lines)
这是一种保持停止线的方法:
def useful_lines(lines, stopterm):
for line in lines:
if stopterm in line:
yield line
break
yield line
usefullines = useful_lines(lines, stopterm)
# or...
for line in useful_lines(lines, stopterm):
# ... do stuff
pass
答案 1 :(得分:5)
“我希望有1个思想 - > 1个Python行映射。”难道我们都不会喜欢以某种方式反映我们自然语言的编程语言吗?
你可以做到这一点,你只需要定义一次你独特的想法。然后你有你希望的1:1映射。
def usefulLines( aFile ):
for line in aFile:
yield line
if line == stopterm:
break
几乎就是这样。
for line in usefulLines( aFile ):
# process a line, knowing it occurs BEFORE stopterm.
有更多一般方法。 lassevk
和enum_while
的{{1}}答案是这种简单设计模式的概括。
答案 2 :(得分:2)
那个itertools解决方案很整洁。我之前对一个方便的工具itertools.groupby感到惊讶。
但是,如果没有itertools我能做到这一点,我只是在修补。所以这就是 (虽然有一个假设和一个缺点:文件不是很大,它分别在线上进行一次额外的完整迭代。)
我创建了一个名为“try”的示例文件:
hello
world
happy
day
bye
一旦你读到文件并在变量名称行中包含行:
lines=open('./try').readlines()
然后
print [each for each in lines if lines.index(each)<=[lines.index(line) for line in lines if 'happy' in line][0]]
给出了结果:
['hello\n', 'world\n', 'happy\n']
和
print [each for each in lines if lines.index(each)<=[lines.index(line) for line in lines if 'day' in line][0]]
给出了结果:
['hello\n', 'world\n', 'happy\n', 'day\n']
所以你得到了最后一行 - 也包括停止期限行。
答案 3 :(得分:1)
留下答案,但将其标记为社区。有关正确的方法,请参阅Stewen Huwig的答案。
嗯,[x for en in enumerable]将运行,直到enumerable不再生成数据,if-part将允许你沿途过滤。
你可以做的是添加一个功能,并通过它过滤你的可枚举:
def enum_until(source, until_criteria):
for k in source:
if until_criteria(k):
break;
yield k;
def enum_while(source, while_criteria):
for k in source:
if not while_criteria(k):
break;
yield k;
l1 = [k for k in enum_until(xrange(1, 100000), lambda y: y == 100)];
l2 = [k for k in enum_while(xrange(1, 100000), lambda y: y < 100)];
print l1;
print l2;
当然,它看起来并不像你想要的那么好......
答案 4 :(得分:1)
我认为保持这种方式很好。复杂的单行并不是真正的pythonic,因为Guido不得不在某个地方设置限制,我想这就是它......
答案 5 :(得分:0)
我会使用Steven Huwig's或S.Lott's解决方案进行实际使用,但作为一个稍微狡猾的解决方案,这是获取此行为的一种方法:
def stop(): raise StopIteration()
usefullines = list(stop() if stopterm in line else line for line in file)
有点滥用这样一个事实:任何引发StopIteration的东西都会中止当前的迭代(这里是生成器表达式),并且比你想要的语法更难以阅读,但是会有效。