与其在对dict 的单个调用中嵌入生成器表达式,不如在处理输入时构建您的dict。
n = 1000
students = {}
for _ in range(n):
x = input("enter students name and grade. Example 'Student C: '")
if x == "quit":
break
# You might want to do more error checking here.
student, grade = x.split()
students[student] = grade
更高级一点,如果输入quit,您可以使用iter(见下文)的两个参数形式终止循环,并使用itertools.islice将循环限制为n条目。
from itertools import islice
n = 1000
students = {}
for x in islice(iter(lambda: input("..."), "quit"), n):
student, grade = x.split()
students[student] = grade
您可能会注意到,这允许您(在拆分输入行时忽略任何错误检查)在调用 dict 时回到您最初的生成器想法:
from itertools import islice
n = 1000
students = dict(x.split() for x in islice(iter(lambda: input("..."), "quit"), n))
最后,如果您只使用n 作为a 方式来避免永远读取输入,您可以省略它,因为用户现在可以随时输入quit: p>
students = dict(x.split() for x in iter(lambda: input("..."), "quit"))
另外,创建零参数可调用以用作iter 的第一个参数的另一种方法是使用functools.partial:
from functools import partial
students = dict(x.split() for x in iter(partial(input, "..."), "quit"))
iter(x, y) 是做什么的?
(iter的双参数形式接受一个函数重复调用,并产生该函数的返回值,直到该函数返回第二个参数。iter(lambda: input("..."), n)相当于
def iter(f, stop):
while True:
x = f()
if x == stop:
break
yield x
)
islice(x, y) 是做什么的?
这会产生一个新的迭代器,如果它有多个 y 元素,则它只返回 x 的第一个 y 元素。大致相当于
def islice(x, y):
while y:
yield next(x)
y -= 1