【问题标题】:Create a list with a value in it using only pure functions - python仅使用纯函数创建一个包含值的列表 - python
【发布时间】:2022-01-24 11:13:00
【问题描述】:

为什么这个问题没有简单的解决方案是因为我只需要使用pure functions来解决。

仅使用 Python 函数式编程页面 (https://docs.python.org/3/howto/functional.html#) 中的纯函数,如何创建一个包含值的列表? 如果我们想创建一个包含值的列表它,我们(在代码中)只是这样做

x = [1]

我不认为[] 是我们在此处查看的函数的一部分,因为它没有签名并且不能像任何其他函数一样调用。

仅使用函数来做到这一点并不是那么简单。我的一个想法是使用list() 创建一个新列表,然后将值附加到它。但是list().append 是可变的,不会返回包含项目的新列表或列表。

我真正想做的是将["a","b","c"] 变成[["a"],["b"],["c"]],具有上述限制。

已经提出了其他建议,例如创建我自己的(纯)函数来做我想做的事情:

def create_list(value) -> list:
    return [value]

然后只需执行map(create_list, ["a","b","c"]) 即可获得解决方案。 但这是一个定制函数,不是来自任何 python 包函数(在https://docs.python.org/3/howto/functional.html 内,如前所述)

【问题讨论】:

  • 仅设置 x = [1] 有什么“不起作用”?
  • 我不明白为什么要这样做
  • x = [1] 是功能性的,但我需要使用纯函数。 [] 没有功能
  • @DavidMeu 是的,但这只是获取一个元组并转换为一个列表。还不如把列表转成自己list([1])
  • @RikardOlsson [1] 算作纯粹的功能性。它没有副作用。它创建一个对象并返回它。您可以使用像 lambda *args: list(args) 这样的 lambda 表达式,但它的作用完全相同

标签: python functional-programming


【解决方案1】:

单个元素:

def to_list(elem):
    return list(range(elem, elem+1)))

通过列表理解将[1,2,3] 转换为[[1], [2], [3]](可以轻松更改为map):

return [to_list(el) for el in input_list]

并且没有(丑陋,但有效^^)

import itertools

def make_gen(elem):
    yield elem

def to_list(elem):
    return list(make_gen(elem))

def helper(elem, l):
    return list(itertools.chain(to_list(to_list(elem)), l))

def convert(l):
    if not l:
        return []
    return helper(l[0], convert(l[1:]))


print(convert([1, 2, 3]))

【讨论】:

  • 那个确实解决了它。聪明的!你知道如何使用相同的想法,但将 [1,2,3] 变成 [[1], [2], [3]]?我会更新问题,所以我的问题的具体实例是
  • 输入列表可以有任意长度吗?如果是这样,我们可能需要在这里使用列表综合,你反对,对吗?
  • 这也很棒,这里的make_gen 做了我在docs.python.org/3/howto/functional.html 中找不到的任何功能。为什么会这样??
  • 你可以 - 它是一个生成器,有一个关于它们的部分
  • 不,我必须在代码中定义一个函数,它是一个生成器。我无法使用这些部分中的预定义函数来实现这一目标
【解决方案2】:

仅使用 Python 函数式编程页面中的纯函数 (https://docs.python.org/3/howto/functional.html#),如何创造 一个包含值的列表?如果我们想创建一个编号为 1 的列表 在里面

您可能会利用生成器,因为生成器描述如下

def justone():
    yield 1
lst = list(justone())
print(lst)

输出

[1]

justone 是函数(可以使用inspect.isfunction 检查)并且是纯的(因为它不会改变外部的任何内容)

【讨论】:

    【解决方案3】:
    lst=[1,2,3];
    #this will print [[1],[2],[3]]
    print(list(map(lambda x: [x],lst)));
    

    【讨论】:

    • 你那里有[x],这基本上是问题的本质
    • @RikardOlsson 我不明白为什么这会是个问题。您还可以使用 F# 或 Haskell 等函数式语言创建列表。
    • 我想我的问题表述有点不清楚。这不是问题,但问题是如何仅使用来自docs.python.org/3/howto/functional.html 的函数来实现相同的结果。您的解决方案是使用lambda x: [x],其中未定义
    【解决方案4】:

    在您链接的文档中,有对迭代器和生成器的引用,它们是 Python(和其他语言)中存在的强大构造。您可以考虑如下构建列表的函数:

    def list_from_args(*args):
        return [*args]
    

    这是迭代器功能的(多余的)包装器。您可以利用 Python 中的迭代器模式来完成很多工作,无论是创建/使用对象(例如列表、元组、字典),还是处理数据(例如,逐行读取/写入文件、对 API 进行分页)或数据库查询等)

    上面的代码做了如下的事情,例如:

    >>> example = list_from_args(1, 'a', 'ham', 'eggs', 44)
    >>> example
    [1, 'a', 'ham', 'eggs', 44]
    

    我将上述功能标记为多余的原因:通常,如果您需要即时创建列表,可以使用list comprehensions

    【讨论】:

      【解决方案5】:

      为确保不可变性,您可能希望使用元组而不是列表(或者对您的列表非常自律)。

      使用列表推导是一种有效的函数式方法:

      A = [1,2,3]
      B = [ [i] for i in A ]        # [[1], [2], [3]]
      

      或使用元组:

      A = (1,2,3)
      B = tuple( (i,) for i in A )  # ((1,), (2,), (3,))
      

      如果你必须使用函数,那么 map() 可能是一个很好的解决方案:

      A = [1,2,3]
      B = list(map(lambda i:[i],A))
      

      如果甚至 [i] 被禁止(但为什么会这样),您可以使用 a 函数直接从其参数创建一个列表:

      def makeList(*v): return list(*v)
      
      A = makeList(1,2,3)
      B = makeList(*map(makeList,A))
      
      # combined
      makeList(*map(makeList,makeList(1,2,3)))
      

      顺便说一句,函数式编程不是关于“只使用函数”,它更多的是关于结果的不可变性(以及避免副作用)。你可能想问问是谁派你去追逐这场野鹅。

      【讨论】:

        【解决方案6】:

        这仅使用来自https://docs.python.org/3/library/functional.html的函数

        import functools
        import itertools
        
        map(
            list, 
            map(
                functools.partial(
                    itertools.repeat, 
                    times=1,
                ), 
                [1,2,3]
            )
        )
        

        functools.partial 创建 itertools.repeat 的新函数,其中“times”参数设置为 1。然后列表中的每个值重复一次,并使用 list 函数转换为新列表。

        >>> [[1], [2], [3]]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-12
          • 2015-05-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-17
          相关资源
          最近更新 更多