Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Clojure表达Python的函数式/惯用方式_Python_Clojure_Transformation - Fatal编程技术网

用Clojure表达Python的函数式/惯用方式

用Clojure表达Python的函数式/惯用方式,python,clojure,transformation,Python,Clojure,Transformation,我有一个数据转换,这让我有点困难。我不能用Clojure表达自己,甚至我的Python,我很流利,仍然感觉很恶心 我需要一个数据结构,如: [1, 2, [3, 4], 5, 6] 要生成这样的结构,请执行以下操作: [[1, 2, 3, 5, 6] [1, 2, 4, 5, 6]] def foo(path, acc_list=[[]]): for val in path: if not isinstance(val, list): for

我有一个数据转换,这让我有点困难。我不能用Clojure表达自己,甚至我的Python,我很流利,仍然感觉很恶心

我需要一个数据结构,如:

[1, 2, [3, 4], 5, 6]
要生成这样的结构,请执行以下操作:

[[1, 2, 3, 5, 6]
 [1, 2, 4, 5, 6]]
def foo(path, acc_list=[[]]):
    for val in path:
        if not isinstance(val, list):
            for acc in acc_list:
                acc.append(val)
        else:
            for subval in val:
                new = acc_list[0][:]
                new.append(subval)
                acc_list.append(new)
            del acc_list[0]
    return acc_list

foo([1, 2, [3, 4], 5, 6])
# => [[1, 2, 3, 5, 6], [1, 2, 4, 5, 6]]
其中,每个子集合创建一个新集合,其中包含迄今为止累积的项。我只期望一个层次的嵌套

我的python尝试如下所示:

[[1, 2, 3, 5, 6]
 [1, 2, 4, 5, 6]]
def foo(path, acc_list=[[]]):
    for val in path:
        if not isinstance(val, list):
            for acc in acc_list:
                acc.append(val)
        else:
            for subval in val:
                new = acc_list[0][:]
                new.append(subval)
                acc_list.append(new)
            del acc_list[0]
    return acc_list

foo([1, 2, [3, 4], 5, 6])
# => [[1, 2, 3, 5, 6], [1, 2, 4, 5, 6]]
我想知道Clojure解决方案是什么,以及(更重要的)导致该解决方案的想法

更新

  • 例如,int也可以是关键字或字符串,不一定是有序的,但显然必须保留顺序

  • 通过嵌套,我的意思是它不会像
    [1[2[3[4 5]6]7]8]
    而是更像
    [1[2 3]4[5]6[7 8 9]
    -浅


    • 我确信还有其他方法可以做到这一点,但这里有一种方法

      user.core=> (def x [1, 2, [3, 4], 5, 6])
      #'user.core/x
      user.core=> (defn create-vecs [x]
               =>   (let [sub (first (filter vector? x))
               =>         all (remove vector? x)]
               =>   (vec (map #(vec (sort (conj all %))) sub))))
      #'user.core/create-vecs
      user.core=> (create-vecs x)
      [[1 2 3 5 6] [1 2 4 5 6]]
      

      基本上,你要抓取向量元素和向量的其余部分减去向量元素,然后映射到它们上面,用
      conj
      创建两个新向量。你需要额外的
      vec
      ,因为
      filter
      remove
      返回列表,而不是向量。

      许多Clojure核心库函数的一个重要特性是能够处理惰性(可能无限)序列;因此,我认为一个好的(惯用的)Clojure解决方案能够正确地扩展包含无限延迟序列的子序列的输入。例如:

      [:a :b (range) :c]
      
      应该扩展到

      ((:a :b 0 :c) (:a :b 1 :c) (:a :b 2 :c) (:a :b 3 :c) ...)
      
      如果顶层序列也可以是无限的,并且可以懒洋洋地处理,那就太好了,但是,我认为这对于这个问题是不可能的。(但如果其他人能想出一个切实可行的办法,我会感到惊喜的!)

      以下是我的解决方案:

      (defn expand-subseqs [[x & xs]]
        (when-not (nil? x)
          (let [heads (if (sequential? x) x [x])
                tails (expand-subseqs xs)]
            (if-not tails (map vector heads)
              (for [z tails, y heads] (cons y z))))))
      
      这里的直觉是,您首先递归地处理输入序列的尾部,然后将当前头部的每个可能值前置到每个可能的尾部

      一些示例输出:

      user=> (expand-subseqs [1, 2, [3, 4], 5, 6])
      ((1 2 3 5 6) (1 2 4 5 6))
      user=> (take 5 (expand-subseqs [:a :b (range) :c [true false]]))
      ((:a :b 0 :c true) (:a :b 1 :c true) (:a :b 2 :c true) (:a :b 3 :c true) (:a :b 4 :c true))
      

      此解决方案的一个好处是,通过使用
      cons
      ,我们实际上为每个结果重用表示尾部序列的对象,而不是为每个排列重复整个序列。例如,在上面的最后一个示例中,五个输出中每一个的
      (:c true)
      尾序列实际上是同一个对象。

      感谢您的回复。“只需要一个嵌套级别”的意思是,我不会处理
      [1[2[3 4]5]6]
      类型结构,而是处理[1[2 3]4[5 6]7…]类型结构。但这是值得思考的,再次感谢。噢,INT只是一个例子,我正在将一个字符串编译成一个速记表示形式,然后扩展成一个路径列表,用于构建路径,用于
      get-in
      assoc-in
      update-in
      。为了清楚起见,我将更新这个问题。为什么结果包含两个列表?在一个简短的游戏之后,这看起来像是一张罚单!谢谢