python 3.6 中的映射函数和可迭代对象
Map function and iterables in python 3.6
我继承了一段代码,我需要 运行 在原始位置以外的其他地方进行一些小改动。我正在尝试 map
一个字符串列表,使用 python 3.6(一种我不熟悉的语言)将函数应用于该列表的每个元素。
我想使用 map
而不是列表理解,但现在我怀疑这是否可行。
在下面的示例中,我尝试了 for
循环、yield
(或不)和 next(...)
或不组合的组合,但我无法代码按预期工作。
我想看印刷品:
AAA! xxx
Found: foo
Found: bar
每次计数器 xxx
模 360
为 0
(零)。
我知道 map
函数不执行代码,所以我需要对输入列表的每个元素执行 "apply" 该函数。
但是我无法使它工作。该文档 https://docs.python.org/3.6/library/functions.html#map and https://docs.python.org/3.6/howto/functional.html#iterators 没有太大帮助,我仔细阅读了它,我认为至少下面的注释位之一 (# <python code>
) 应该有效。我不是经验丰富的 python 开发人员,我想我遗漏了一些关于 python 3.6 的 syntax/conventions 关于 iterators/generators 的陷阱。
issue_counter = 0
def foo_func(serious_stuff):
# this is actually a call to a module to send an email with the "serious_stuff"
print("Found: {}".format(serious_stuff))
def report_issue():
global issue_counter
# this actually executes once per minute (removed the logic to run this fast)
while True:
issue_counter += 1
# every 6 hours (i.e. 360 minutes) I would like to send emails
if issue_counter % 360 == 0:
print("AAA! {}".format(issue_counter))
# for stuff in map(foo_func, ["foo", "bar"]):
# yield stuff
# stuff()
# print(stuff)
iterable_stuff = map(foo_func, ["foo", "bar"])
for stuff in next(iterable_stuff):
# yield stuff
print(stuff)
report_issue()
当 运行 运行脚本时,for
循环有很多不同的 errors/unexpected 行为:
- 调用
print(...)
时不打印任何内容
TypeError: 'NoneType' object is not callable
AttributeError: 'map' object has no attribute 'next'
TypeError: 'NoneType' object is not iterable
- 打印我所期望的
None
,例如:
AAA! 3047040
Found: foo
None
Found: bar
None
我发现对 next(iterable_thingy)
的调用实际上调用了映射函数。
在映射输入列表以生成可迭代对象时知道输入列表的长度,意味着我们知道必须调用 next(iterable_thingy)
的次数,因此函数 report_issue
(在我之前的示例中) 像这样定义时按预期运行:
def report_issue():
global issue_counter
original_data = ["foo", "bar"]
# this executes once per minute
while True:
issue_counter += 1
# every 6 hours I would like to send emails
if issue_counter % 360 == 0:
print("AAA! {}".format(issue_counter))
iterable_stuff = map(foo_func, original_data)
for idx in range(len(original_data)):
next(iterable_stuff)
为了解决这个可迭代的问题,我发现 运行 ipython(交互式 REPL)可以检查生成的可迭代对象的类型和文档,如下所示:
In [2]: def foo_func(serious_stuff):
...: # this is actually a call to a module to send an email with the "serious_stuff"
...: print("Found: {}".format(serious_stuff)) ...:
In [3]: iterable_stuff = map(foo_func, ["foo", "bar"])
In [4]: iterable_stuff?
Type: map
String form: <map object at 0x7fcdbe8647b8>
Docstring:
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
In [5]: next(iterable_stuff) Found: foo
In [6]: bar_item = next(iterable_stuff) Found: bar
In [7]: bar_item?
Type: NoneType
String form: None
Docstring: <no docstring>
In [8]:
我继承了一段代码,我需要 运行 在原始位置以外的其他地方进行一些小改动。我正在尝试 map
一个字符串列表,使用 python 3.6(一种我不熟悉的语言)将函数应用于该列表的每个元素。
我想使用 map
而不是列表理解,但现在我怀疑这是否可行。
在下面的示例中,我尝试了 for
循环、yield
(或不)和 next(...)
或不组合的组合,但我无法代码按预期工作。
我想看印刷品:
AAA! xxx
Found: foo
Found: bar
每次计数器 xxx
模 360
为 0
(零)。
我知道 map
函数不执行代码,所以我需要对输入列表的每个元素执行 "apply" 该函数。
但是我无法使它工作。该文档 https://docs.python.org/3.6/library/functions.html#map and https://docs.python.org/3.6/howto/functional.html#iterators 没有太大帮助,我仔细阅读了它,我认为至少下面的注释位之一 (# <python code>
) 应该有效。我不是经验丰富的 python 开发人员,我想我遗漏了一些关于 python 3.6 的 syntax/conventions 关于 iterators/generators 的陷阱。
issue_counter = 0
def foo_func(serious_stuff):
# this is actually a call to a module to send an email with the "serious_stuff"
print("Found: {}".format(serious_stuff))
def report_issue():
global issue_counter
# this actually executes once per minute (removed the logic to run this fast)
while True:
issue_counter += 1
# every 6 hours (i.e. 360 minutes) I would like to send emails
if issue_counter % 360 == 0:
print("AAA! {}".format(issue_counter))
# for stuff in map(foo_func, ["foo", "bar"]):
# yield stuff
# stuff()
# print(stuff)
iterable_stuff = map(foo_func, ["foo", "bar"])
for stuff in next(iterable_stuff):
# yield stuff
print(stuff)
report_issue()
当 运行 运行脚本时,for
循环有很多不同的 errors/unexpected 行为:
- 调用
print(...)
时不打印任何内容
TypeError: 'NoneType' object is not callable
AttributeError: 'map' object has no attribute 'next'
TypeError: 'NoneType' object is not iterable
- 打印我所期望的
None
,例如:
AAA! 3047040 Found: foo None Found: bar None
我发现对 next(iterable_thingy)
的调用实际上调用了映射函数。
在映射输入列表以生成可迭代对象时知道输入列表的长度,意味着我们知道必须调用 next(iterable_thingy)
的次数,因此函数 report_issue
(在我之前的示例中) 像这样定义时按预期运行:
def report_issue():
global issue_counter
original_data = ["foo", "bar"]
# this executes once per minute
while True:
issue_counter += 1
# every 6 hours I would like to send emails
if issue_counter % 360 == 0:
print("AAA! {}".format(issue_counter))
iterable_stuff = map(foo_func, original_data)
for idx in range(len(original_data)):
next(iterable_stuff)
为了解决这个可迭代的问题,我发现 运行 ipython(交互式 REPL)可以检查生成的可迭代对象的类型和文档,如下所示:
In [2]: def foo_func(serious_stuff):
...: # this is actually a call to a module to send an email with the "serious_stuff"
...: print("Found: {}".format(serious_stuff)) ...:
In [3]: iterable_stuff = map(foo_func, ["foo", "bar"])
In [4]: iterable_stuff?
Type: map
String form: <map object at 0x7fcdbe8647b8>
Docstring:
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
In [5]: next(iterable_stuff) Found: foo
In [6]: bar_item = next(iterable_stuff) Found: bar
In [7]: bar_item?
Type: NoneType
String form: None
Docstring: <no docstring>
In [8]: