如何在 Python 3 中使用生成器管道?
How to use generator pipeline in Python 3?
我正在努力提高自己的能力并学习生成器管道。我设法用它解决了一些问题,但我觉得我的理解有一个基本的差距。
例如:
我试图构建一个 return 范围内所有数字的函数。作为几个范围的字符串给出的范围。
因此收到的字符串示例:"1-2,4-4,8-10"
。
所以第一个生成器应该 return 一个整数对列表:[1, 2] [4, 4] [8, 10]
第二个生成器应该使用 1st_gen[0]
作为范围函数的开始,1st_gen[1]
作为范围函数的停止,并且 return 范围内的所有数字:1 2 4 8 9 10
这是我的代码,我很乐意为提高我的技能提供提示:
def parse_ranges(range_string):
temp_list = (c.replace("-", ",") for c in list(range_string.split(",")))
generator2 = (i for start, stop in temp_list for i in range(int(start), int(stop) + 1))
for i in generator2:
print(i)
print(parse_ranges("1-2,4-4,8-10"))
print(parse_ranges("0-0,4-8,20-21,43-45"))
一些修复:
str.split()
return 是一个列表,不需要将其结果放入 list
parse_ranges()
没有 return 任何东西,为什么打印它?
range(int(4), int(4) + 1)
不会 return [4, 4]
而只会 [4]
def parse_ranges(range_string):
temp = (map(int, c.split("-")) for c in range_string.split(","))
# yield all the numbers (yield from 'flattens' the result)
for start, stop in temp:
yield from range(start, stop + 1)
# or to yield lists
# for start, stop in temp:
# yield list(range(start, stop + 1))
print(*parse_ranges("1-2,4-4,8-10"), sep=" ~ ")
print(*parse_ranges("0-0,4-8,20-21,43-45"), sep=" ~ ")
输出(添加 '~'
作为分隔符,因此很清楚,其中产生的元素的“边界”是):
# yield from range(start, stop + 1)
1 ~ 2 ~ 4 ~ 8 ~ 9 ~ 10
0 ~ 4 ~ 5 ~ 6 ~ 7 ~ 8 ~ 20 ~ 21 ~ 43 ~ 44 ~ 45
# yield list(range(start, stop + 1))
[1, 2] ~ [4] ~ [8, 9, 10]
[0] ~ [4, 5, 6, 7, 8] ~ [20, 21] ~ [43, 44, 45]
如果需要,您可以根据需要将过程拆分为多个生成器步骤,例如:
def get_ranges(string):
for part in string.split(","):
yield [int(number) for number in part.split("-")]
def get_numbers(ranges):
for start, stop in ranges:
yield from range(start, stop + 1)
用法:
>>> list(get_numbers(get_ranges("1-2,4-4,8-10")))
[1, 2, 4, 8, 9, 10]
如果你真的想要,你甚至可以把它分成更多的步骤(分成几部分,转换成数字,转换成范围对象,得到数字)。
我正在努力提高自己的能力并学习生成器管道。我设法用它解决了一些问题,但我觉得我的理解有一个基本的差距。
例如:
我试图构建一个 return 范围内所有数字的函数。作为几个范围的字符串给出的范围。
因此收到的字符串示例:"1-2,4-4,8-10"
。
所以第一个生成器应该 return 一个整数对列表:[1, 2] [4, 4] [8, 10]
第二个生成器应该使用 1st_gen[0]
作为范围函数的开始,1st_gen[1]
作为范围函数的停止,并且 return 范围内的所有数字:1 2 4 8 9 10
这是我的代码,我很乐意为提高我的技能提供提示:
def parse_ranges(range_string):
temp_list = (c.replace("-", ",") for c in list(range_string.split(",")))
generator2 = (i for start, stop in temp_list for i in range(int(start), int(stop) + 1))
for i in generator2:
print(i)
print(parse_ranges("1-2,4-4,8-10"))
print(parse_ranges("0-0,4-8,20-21,43-45"))
一些修复:
str.split()
return 是一个列表,不需要将其结果放入list
parse_ranges()
没有 return 任何东西,为什么打印它?range(int(4), int(4) + 1)
不会 return[4, 4]
而只会[4]
def parse_ranges(range_string):
temp = (map(int, c.split("-")) for c in range_string.split(","))
# yield all the numbers (yield from 'flattens' the result)
for start, stop in temp:
yield from range(start, stop + 1)
# or to yield lists
# for start, stop in temp:
# yield list(range(start, stop + 1))
print(*parse_ranges("1-2,4-4,8-10"), sep=" ~ ")
print(*parse_ranges("0-0,4-8,20-21,43-45"), sep=" ~ ")
输出(添加 '~'
作为分隔符,因此很清楚,其中产生的元素的“边界”是):
# yield from range(start, stop + 1)
1 ~ 2 ~ 4 ~ 8 ~ 9 ~ 10
0 ~ 4 ~ 5 ~ 6 ~ 7 ~ 8 ~ 20 ~ 21 ~ 43 ~ 44 ~ 45
# yield list(range(start, stop + 1))
[1, 2] ~ [4] ~ [8, 9, 10]
[0] ~ [4, 5, 6, 7, 8] ~ [20, 21] ~ [43, 44, 45]
如果需要,您可以根据需要将过程拆分为多个生成器步骤,例如:
def get_ranges(string):
for part in string.split(","):
yield [int(number) for number in part.split("-")]
def get_numbers(ranges):
for start, stop in ranges:
yield from range(start, stop + 1)
用法:
>>> list(get_numbers(get_ranges("1-2,4-4,8-10")))
[1, 2, 4, 8, 9, 10]
如果你真的想要,你甚至可以把它分成更多的步骤(分成几部分,转换成数字,转换成范围对象,得到数字)。