打印来自Python生成器的所有结果

时间:2019-01-01 16:29:14

标签: python python-3.x generator

我制作了一个生成器函数,可以使用关键字搜索csv文件,并且如果有问题,我想打印结果。我该如何做而又不用一遍又一遍地使用print(next(gen_results))?

当关键字与联系人没有匹配但我想要更简洁的解决方案时,我尝试了stopIteration的try-catch语句。

def search(keyword, filename):
    f = open(filename, 'r')
    for line in f:
        if keyword in line:
            yield line
    f.close()

the_generator = search('Python', 'contacts.csv')
print(next(the_generator))
print(next(the_generator))  

contacts.csv
Name01, 89888
Name02, 8885445
Name03, 54555
Name04, 55544584
Name05, 55855
Python, 100
BigPi, 444
Python, 101

如果没有与关键字的联系,我希望输出为“ Nothing Found”的语句。如果有使用该关键字的联系人,则会输出所有列表。

4 个答案:

答案 0 :(得分:2)

请尝试

def search(keyword, filename):
    f = open(filename, 'r')
    for line in f:
        if keyword in line:
            yield line
        else:
            yield 'Nothing Found'
    f.close()

the_generator = search('Python', 'contacts.csv')
for g in the_generator:
    print(g)

“ the_generator”是一个迭代对象,“ for”循环需要一个迭代对象才能运行。程序的输出将是:

Nothing Found
Nothing Found
Nothing Found
Nothing Found
Nothing Found
Python, 100 

答案 1 :(得分:1)

def search(keyword, filename):
    f = open(filename, 'r')
    for line in f:
        if keyword in line:
            yield line
    f.close()

the_generator = search('Python', 'contacts.csv')
my_list=list(the_generator)
if not my_list:
    print("Not Found")
for item in my_list:
    print(item.strip())

答案 2 :(得分:1)

您可以将“未找到”测试放入生成器本身:

def search(keyword, lines):
    cnt = 0
    for line in lines:
        if keyword in line:
            cnt += 1
            yield line
    if cnt==0:
        yield "NOT FOUND"

In [166]: txt = """Name01, 89888
     ...: Name02, 8885445
     ...: Name03, 54555
     ...: Name04, 55544584
     ...: Name05, 55855
     ...: Python, 100
     ...: BigPi, 444
     ...: Python, 101
     ...: """.splitlines()
In [167]: for x in search("Python",txt):print(x)
Python, 100
Python, 101
In [168]: for x in search("Foobar",txt):print(x)
NOT FOUND

否则,我认为最简单的方法是list生成器,并检查一个空列表。就其本身而言,生成器机制不计算yields的数量。

答案 3 :(得分:0)

有几种消耗生成器的方法-取消next()的使用仅消耗生成器的(下一个)值。

生成文件:

def gen_file():
    with open("contacts.csv","w") as f:
        f.write("""Name01, 89888
Name02, 8885445
Name03, 54555
Name04, 55544584
Name05, 55855
Python, 100
BigPi, 444
Python, 101
""")

使用它:

gen_file()   

def search(keyword, filename="contacts.csv"):
    """Changed to use .. with open() as f: ... style syntax."""
    with open(filename, 'r') as f:
        for line in f:
            if keyword in line:
                yield line 


# consume all of it into a list - you can reuse it
print("-"*40)
the_generator = search('Python', 'contacts.csv')
contacts = list(the_generator)
print(*contacts, sep="")


print("-"*40)
# decompose the generator directly for printing
the_generator = search('Python', 'contacts.csv')
print(*the_generator, sep="" ) 


print("-"*40)
# use a for loop over the generated results
the_generator = search('Python', 'contacts.csv')
for li in the_generator:
    print(li, end="") # remove end=\n


print("-"*40)
# using str.join to create the output
the_generator = search('Python', 'contacts.csv')
print("".join(the_generator))


print("-"*40)
# loop endlessly until StopIteration is raised
try:
    while True:
        print(next(the_generator), end="")
except StopIteration:
    pass

输出(多次):

----------------------------------------
Python, 100
Python, 101

如果不重用生成的值,“最佳”值可能是print(*the_generator,sep="")或更明确的值:

# use a for loop over the generated results
the_generator = search('Python', 'contacts.csv')
for li in the_generator:
    print(li,end="") # remove end=\n

您可能还想在这里阅读:Using yield from with conditional in python