`
cookoo
  • 浏览: 646389 次
  • 性别: Icon_minigender_1
  • 来自: Shanghai
社区版块
存档分类
最新评论

List comprehension和递归的巧妙结合

    博客分类:
  • FP
阅读更多
我以前总以为list comprehension这个语法糖不过就是些map,filter转换罢了,最近看到Haskell和Erlang的递归用法来实现排列,比循环方法要简洁很多:

Haskell:
java 代码
  1. permutation [] = [[]]     
  2. permutation xs = [x:ys | x <- xs, ys <- permutation (delete x xs)]  

Erlang:
java 代码
  1. permutation([]) -> [[]];  
  2. permutation(L)  -> [[H|T] || H <- L, T <- permutation(L--[H])].  

应用举例

AlbertLee出的一道面试题: http://www.douban.com/group/topic/1237059/
用1、2、2、3、4、5这六个数字(注意有两个2), 打印出所有不同的排列,如:512234、412325等,要求:"4"不能在第三位,"3"与"5"不能相连。

我稍微改了一下的Haskell解法如下:
java 代码
 
  1. module Main where   
  2. import List   
  3.    
  4. inlist [] [] = True   
  5. inlist a [] = False   
  6. inlist a [x] = False   
  7. inlist a (x:nx) = (a == [x, head nx] || a == [head nx, x]) || inlist a nx   
  8. notinlist a b = not (inlist a b)  --不相连判断 
  9.    
  10. permutation [] = [[]]   
  11. permutation xs = [x:ys | x <- xs, ys <- permutation (delete x xs)]  --排列 
  12.    
  13. third list = list!!2 /= 4  --第三位判断,这个硬编码啦 
  14.    
  15. s = [1,2,2,3,4,5]   
  16. res2 = filter (notinlist [3,5]) $ filter third $ nub $ permutation s     
  17. main = print (length res2)  


更新

Erlang在语法上和Haskell有不少类似如list comprehension,pattern match和immutable data,语意上则要简单很多,没有太多新概念比如lazy evaluation:

java 代码
 
  1. fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]  

这个使用递归的list comprehension来计算fibonacci数的方法Erlang是没法照搬的,因为fibs是个无限list。

更新2:

新版F#终于也增加了list comprehension,这样在F#可以写成:
java 代码
 
  1. let delete item list = List.filter (fun x -> x <> item) list  
  2.   
  3. let rec permutation x = match x with  
  4.   |[] -> [[]]  
  5.   |xs -> [for x in xs for y in permutation (delete x xs) -> x::ys]  



分享到:
评论
5 楼 cookoo 2007-01-16  
随机数每次输出都会不同,实际上内部依赖于某种状态也就是有side effect,需要用monad封装:
import List
import Random

randomPerm :: [a] -> StdGen -> [a] 
randomPerm list gen = map (list!!) rl 
  where l = length list
        rl =  take l $ nub $ randomRs (0,l - 1) gen

randomPermIO :: [a] -> IO [a]
randomPermIO list = do
  g <- newStdGen
  return $ randomPerm list g  


randomPerm是个pure的函数,结果完全依赖参数。randomPermIO每次产生一个新的随机数产生器,供randomPerm使用。
4 楼 快乐的小猪 2007-01-14  
您好,看了你写的东西很受启发,我是初学者,正为Haskell的很多问题而困扰着.比如 这个 IO 怎么理解呐?  对于这个问题, 如您上面讲的Permutation排列问题,如果用随机的(Random)方法该怎样实现?看了不少资料,就是似懂非懂. 晕啊. 

函数是这样表示:

RandomPermt :: Ord a=> [a]-> IO[a]


3 楼 T55555 2007-01-08  
Have a look at ...
http://davidtran.doublegifts.com/blog/?p=5
module Main where
import Data.List

permutations [] = [[]]
permutations xs = [x:ps | x <- nub xs, ps <- permutations (delete x xs)]

digits = [1,2,2,3,4,5]

check xs =
  xs !! 2 /= 4  &&
  abs (p3 - p5) /= 1
  where
    Just p3 = elemIndex 3 xs
    Just p5 = elemIndex 5 xs

result = filter check (permutations digits)

main = do
--  print result
    print (length result)
2 楼 zhangyu8374 2006-12-01  
comprehension确实挺狠的。

看看这个,也是comprehension的体现,太自然了!
my_concat :: [[a]]->[a]
my_concat xss = [x|xs<-xss,x<-xs]
1 楼 dogstar 2006-11-26  
很羡慕你可以由着性子去学习,特别是能容易买到原版的书。哈哈。

相关推荐

    Python进阶内容 List Comprehension _python_

    在Python中,列表推导式(List Comprehension)是处理和构建列表的高级语法,尤其适用于需要对现有列表进行操作或者基于某种条件生成新列表的场景。 列表推导式的语法结构如下: ```python [expression for item in...

    python中的list,set,dict comprehension详解

    在Python中,List Comprehension是一种创建新列表的方法,它通过一行代码就能完成对已有列表的遍历、筛选和转换。基本语法结构如下: ```python new_list = [expression for item in iterable if condition] ``` ...

    python中lambda函数 list comprehension 和 zip函数使用指南

    lambda 函数 Python 支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做 lambda 的函数,是从 Lisp 借用来的,可以用在任何需要函数的地方。 def f(x): return x*2,用lambda函数来替换可以写成:g = ...

    Machine Reading Comprehension 调研.docx

    Machine Reading Comprehension (MRC) 是自然语言处理领域的一个关键任务,旨在让计算机理解文本并回答相关问题。这个任务涵盖了多种技术和方法,包括深度学习模型、注意力机制和自训练策略等。 一、BIDAF:双向...

    Neural Reading Comprehension and Beyond

    'Neural Reading Comprehension and Beyond' 毕业论文上传斯坦福大学图书馆仅四天就获得了上千次的阅读量,成为了斯坦福大学近十年来最热门的毕业论文之一,她的这篇毕业论文主要研究神经网络阅读理解和问答,...

    Python递归实现打印多重列表代码

    这里使用了列表推导式(List Comprehension),它是一种简洁、高效的创建新列表的方式。列表推导式的语法形式为`[expression for item in iterable if condition]`,其中`expression`是要生成的新列表中的表达式,`...

    python常见面试题15道

    Python 基础知识点总结 Python 是一种解释型语言,具有动态类型、面向对象编程、函数作为第一类对象等特点。Python 代码编写快,但...* 问题 3:Python 的数据结构和操作,包括 dict、range 和 list comprehension。

    Python-中LIST操作.docx

    9. **列表推导式**(List Comprehension): 这是一种简洁的创建列表的方式,例如`[ &lt;expr1&gt; for k in L if &lt;expr2&gt; ]`,它根据条件`expr2`过滤`L`中的元素并应用表达式`expr1`。 10. **字典(Dictionary)**: ...

    Intermediate Listening Comprehension.xdf

    Intermediate Listening Comprehension.xdf

    Paragraph comprehension - ASVAB Section Eight Paragraph comprehension认证题库.docx

    ASVAB Paragraph Comprehension部分是ASVAB( Armed Services Vocational Aptitude Battery)考试中的一个环节,旨在测试考生理解并推断出书面文本信息的能力。这个认证题库包含了多种类型的阅读理解题目,帮助考生...

    Q703207 list如何实现动态分组

    result = dynamic_grouping_with_list_comprehension(lst, key_func) ``` 在实际应用中,我们需要根据具体的需求选择合适的分组方法。例如,如果数据量很大且不希望排序,可以使用自定义函数;如果数据已经有序且...

    NEURAL READING COMPREHENSION AND BEYOND

    斯坦福大学博士毕业生Danqi Chen撰写的这篇论文《NEURAL READING COMPREHENSION AND BEYOND》,是一篇详细探讨神经网络在自然语言理解领域应用的综述性论文。自然语言理解(NLU)是人工智能(AI)的核心挑战之一,它...

    Python列表list操作相关知识小结

    列表生成式(List Comprehension)是Python的一个特色,它可以快速生成新的列表,根据已有的列表或其他迭代器进行计算: ```python list_d = [i for i in list_a] list_e = [i*j for i in list_a for j in list_c] ...

    python判断两个列表中相同和不同的元素

    为了检查这两个列表的异同,我们可以使用列表推导式(List Comprehension)来快速找出它们的交集和并集。 1. 交集(两个列表中都存在的元素): ```python a = [x for x in list1 if x in list2] ``` 这行代码...

    Python列表list数组array常用操作集锦.docx

    * 使用列表生成式(list comprehension)创建列表 例如: ```python sample_list = ['d', 1, ('d', 'b')] ``` 列表操作 访问列表元素 可以使用索引来访问列表元素,例如: ```python value_start = sample_list[0...

    5.玩转Python中的List1

    最后,列表推导式(List Comprehension)是Python的一种高效语法,用于创建新列表。它允许我们根据现有列表的元素生成新的列表,通常用于过滤、映射和转换操作。 综上所述,理解和掌握这些关于Python中List的基本...

    Chinese Machine Reading Comprehension and Beyond.pdf

    MRC是人工智能中理解和处理人类语言的关键技术,它涉及让机器读取文本段落并回答相关问题。 教程涵盖了几个核心话题。首先,回顾了中文机器阅读理解的发展,包括一系列中文MRC数据集,如PD&CFT和CMRC 2018,它们...

    5-Comprehension and Knowledge.rar

    《5-Comprehension and Knowledge》的压缩包文件主要涵盖了理解和知识的相关主题,这在人工智能(AI)领域,特别是自动问答(AIGC)和知识图谱(KG)的应用中至关重要。以下是对这些主题的详细解析: 理解是人工...

    python基础教程:Python中在for循环中嵌套使用if和else语句的技巧

    for…[if]…构建List (List comprehension) 1.简单的for…[if]…语句 Python中,for…[if]…语句一种简洁的构建List的方法,从for给定的List中选择出满足if条件的元素组成新的List,其中if是可以省略的。下面举几...

    Mechanical Comprehension - ASVAB Section Three Mechanical Comprehension题库.docx

    ASVAB( Armed Services Vocational Aptitude Battery)是美国军队入伍资格测试,其中的Mechanical Comprehension部分考察的是考生对机械原理的理解和应用能力。这个部分涉及到杠杆、简单机器、齿轮、摩擦力、压力、...

Global site tag (gtag.js) - Google Analytics