【问题标题】:How do I write a "generator" function that produces the elements of the following list. List = [1,3,4,"hello", 5, 3,4,"create"]如何编写生成以下列表元素的“生成器”函数。列表 = [1,3,4,"hello", 5, 3,4,"create"]
【发布时间】:2018-09-10 18:37:24
【问题描述】:

a) 我想创建一个生成器函数来生成列表中的元素 = [1,3,4,"hello", 5,3,4, "create"]。

b) 然后我想创建一个新列表,该列表使用创建的相同生成器函数仅使用唯一元素排序。

这适用于 a) 还是因为 for 循环而破坏了使用生成器的目的?

def generate(list):
    for i in list:
        yield(i)

produce = generator(list)

【问题讨论】:

  • “我想创建一个生成器函数来生成列表的元素”——为什么?
  • “这对 a) 有效还是因为 for 循环而破坏了使用生成器的目的?” - 那么,您的目的到底是什么?想把它当作发电机吗?
  • 这是课堂作业
  • 你为什么要问 我们 它是否适用于 (a) 部分。运行它,看看你得到了什么! :-) 在您的代码出现已知问题之前,您不会遇到 Stack Overflow 问题。
  • 生成器的主要好处之一是它们可以比传统列表占用更少的空间。但是,如果您要获取生成器的输出并对其进行排序,那么您需要一次将所有数据存储在内存中,这样您就失去了最初节省的内存。我会说这违背了目的。

标签: python list iterator generator


【解决方案1】:

大多数时候,您所关心的只是拥有一个可迭代的对象——您可以在 for 循环中使用它。

列表已经是其元素的可迭代对象。 for elem in lst:for elem in generate(lst): 都可以,实际上效率会更高。


有时,您特别需要一个迭代器——一个跟踪其当前位置的迭代器,以便您可以在其上调用next。例如,如果您想将一个可迭代对象分组为 2 个值的元组,那么最简单的方法是在可迭代对象上使用迭代器。

但是内置的iter 函数已经做到了这一点——您可以使用iter(lst)generate(lst),同样,它会更高效。


很少,您特别需要一个生成器——一个提供一些额外方法的迭代器。我不确定你为什么需要一个只遍历列表的函数,因为它没有任何用处 do 用这些额外的方法,但也许有人写了一些愚蠢的函数来检查isinstance(g, types.GeneratorType) 并拒绝使用列表或列表迭代器,您无法更改该功能。

但即使在这种情况下,您也可以只编写一个生成器表达式(i for i in lst),而不是generate(lst)


最后,您可能不仅需要一个生成器,还需要一个返回生成器的函数。也许您需要将其作为回调传递,以便稍后调用;我不知道。

在这种情况下,你写的东西是有道理的。但是,除非您使用的是 Python 2.7 或 3.2 或更早版本,否则您可能仍想使用yield from

def generate(lst):
    yield from lst

然后我想创建一个新列表,该列表使用创建的相同生成器函数仅使用唯一元素排序。

没有理由在这里使用生成器函数,当您只需要一个可迭代对象时——但如果您需要将它用于某些任务,那么您没有理由不能。事实上,它与使用列表没有什么不同。

如果您想对列表中的唯一值进行排序,您可以进行唯一化和排序:

sorted_uniques = sorted(set(lst))

…或排序和唯一化(例如,使用itertools 文档中的unique_justseen 配方):

sorted_uniques = list(unique_justseen(sorted(lst)))

你如何用你的发电机做同样的事情?只需通过生成器 而不是列表:

sorted_uniques = sorted(set(generate(lst)))

【讨论】:

  • 非常感谢!但列表是字符串和整数的混合,所以不知道如何排序!
  • @jan93 好吧,你必须决定;没有其他人可以决定你想要什么。明显的可能性包括:(1) 将数字视为它们的字符串表示形式,(2) 将所有数字放在所有字符串之前,(3) 将所有数字放在所有字符串之后,(4) 将数字视为它们的字符串表示形式,但然后“自然排序”字符串,例如,“11”在“3”之后。但是你可以想出各种疯狂的东西,比如将字符串视为基数为 40 亿的整数,其中每个 Unicode 字符都是一个数字。只要你能描述你想要什么,你就可以编码。
【解决方案2】:

您拥有的generate(list) 函数已经足以完成您问题的前半部分:只需将所需的列表传递给它。但是,如果您希望始终返回该列表的生成器,则可以对其进行硬编码:

def generate():
    _list = [1, 3, 4, "hello", 5, 3, 4, "create"]
    for obj in _list:
        yield(obj)

要快速去除重复项,您可以将返回列表(或生成器)转换为一个集合:

x = set(generate())

要对其进行排序,只需将其转换回列表并对其进行排序:

y = sorted(list(x))

【讨论】:

  • 感谢您的回答!我最初做了类似的事情,但由于列表是字符串和整数的混合,我不确定你能做到这一点 - 你知道如何进行排序吗?
猜你喜欢
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2014-06-10
  • 2020-12-22
  • 1970-01-01
  • 2019-03-06
  • 1970-01-01
相关资源
最近更新 更多