Python实现的生成自我描述脚本分享(很有意思的程序)


Posted in Python onJuly 18, 2014

自我描述的语句指这样一种语句:它的内容就是对它本身的描述。(废话……)比如下面这句句子:

这是一段自我描述的语句,除了标点符号外,它共包含125个字符,其中33个“个”,29个“2”,5个“3”,3个“符”,3个“5”,2个“一”,2个“它”,2个“包”,2个“的”,2个“标”,2个“了”,2个“我”,2个“外”,2个“含”,2个“中”,2个“是”,2个“1”,2个“段”,2个“点”,2个“描”,2个“9”,2个“字”,2个“这”,2个“句”,2个“除”,2个“自”,2个“语”,2个“共”,2个“述”,2个“号”,2个“其”。

这句话是我用一段 Python 脚本生成的,生成原理大致如下:

1、给出一个模板,让句子的各个内容知道自己该出现在哪个部位;
2、根据当前信息,生成句子;
3、将当前句子作为输入,再次执行第 2 步的操作;
4、直到句子各部分内容的信息都正确。

简单来说,就是一个不断迭代修正的过程。

其中需要注意的是,每次迭代时应该尽量只改动一个地方,以免两处同时变化相互影响,造成死循环;另外,如果句子中有多处地方需要修正,尽量随机选取一处进行修正,而不要按一定顺序进行修正,同样是为了减少陷入死循环的风险。

不过,即使如此,某些情况下还是有可能陷入死循环,比如如果某一步得到了下面这样的句子:

这句很 2 的话包含 3 个“2”。

上面这句话明显是错误的,因为其中只有两个“2”。那么,我们把那个“3”改为“2”,是不是就对了呢?很容易发现,如果我们做了这样的改动之后,句子将变成:

这句很 2 的话包含 2 个“2”。

这时,句子中又包含三个“2”了。像这样的句子就似乎无法简单地改为正确的自我描述语句,因为无论如何改都会陷入死循环。

最后,我用来生成最上面的那句自我描述语句的 Python 脚本如下:

# -*- coding: utf-8 -*-

import random

class SelfDesc(object):

  ignore_chars = u",。“”"

  def __init__(self, template):

    self.template = template
    self.length = 0
    self.detail = ""
    self.content = ""
    self.chars = ""
    self.char_count = {}
    self.makeContent()
    self.char_count = self.getCharCount()
    self.getCharCount()
    self.makeContent()


  def __str__(self):

    return self.content


  def makeContent(self):

    self.makeDetail()
    self.content = self.template.replace(u"{length}", u"%d" % self.length)
      .replace(u"{detail}", self.detail)
    self.getChars()


  def getChars(self):

    chars = self.content
    for c in self.ignore_chars:
      chars = chars.replace(c, "")

    self.chars = chars
    return chars


  def getLength(self):

    self.length = len(self.chars)


  def getCharCount(self):

    d = {}
    for c in self.chars:
      if c in self.ignore_chars:
        continue
      d.setdefault(c, 0)
      d[c] += 1

    return d


  def makeDetail(self):

    d = self.char_count
    items = d.items()
    items.sort(key=lambda x: -x[1])

    s = []
    for c, n in items:
      s.append(u"%d个“%s”" % (n, c))

    self.detail = u",".join(s)


  def correct(self):

    print "-" * 50

    char_count = self.getCharCount()
    items = char_count.items()
    random.shuffle(items)
    for c, n in items:
      if n <= 1 and c in self.char_count:
        del self.char_count[c]
        continue

      if self.char_count.get(c) == n:
        continue
      else:
        self.char_count[c] = n
        return True

    else:
      len = self.length
      self.getLength()

      if len != self.length:
        return True

    return False


  def generate(self):

    icount = 0
    while self.correct():
      icount += 1
      self.makeContent()
      print u"#%d %s" % (icount, self)


def main():

  template = u"这是一段自我描述的语句,除了标点符号外,它共包含{length}个字符,其中{detail}。"
  sd = SelfDesc(template)
  sd.generate()
  print u"%s" % sd


if __name__ == "__main__":
  main()
Python 相关文章推荐
Python排序搜索基本算法之选择排序实例分析
Dec 09 Python
python3基于TCP实现CS架构文件传输
Jul 28 Python
使用Python操作FTP实现上传和下载的方法
Apr 01 Python
用python生成(动态彩色)二维码的方法(使用myqr库实现)
Jun 24 Python
在matplotlib中改变figure的布局和大小实例
Apr 23 Python
为什么说python适合写爬虫
Jun 11 Python
利用Python的folium包绘制城市道路图的实现示例
Aug 24 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
Sep 01 Python
5款实用的python 工具推荐
Oct 13 Python
python图片合成的示例
Nov 09 Python
在 Golang 中实现 Cache::remember 方法详解
Mar 30 Python
基于PyQt5制作一个群发邮件工具
Apr 08 Python
Python中使用 Selenium 实现网页截图实例
Jul 18 #Python
Python中使用PyHook监听鼠标和键盘事件实例
Jul 18 #Python
python中使用pyhook实现键盘监控的例子
Jul 18 #Python
python使用pyhook监控键盘并实现切换歌曲的功能
Jul 18 #Python
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
Jul 18 #Python
python采集博客中上传的QQ截图文件
Jul 18 #Python
Python下singleton模式的实现方法
Jul 16 #Python
You might like
关于ThinkPHP中的异常处理详解
2018/05/11 PHP
php+js实现的无刷新下载文件功能示例
2019/08/23 PHP
JQuery在光标位置插入内容的实现代码
2010/06/18 Javascript
教您去掉ie网页加载进度条的方法
2010/12/09 Javascript
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
2011/04/16 Javascript
火狐textarea输入法的bug的触发及解决
2013/07/24 Javascript
简单的js图片轮换代码(js图片轮播)
2014/05/06 Javascript
jquery插件推荐浏览器嗅探userAgent
2014/11/09 Javascript
jQuery往返城市和日期查询实例讲解
2015/10/09 Javascript
Jquery中巧用Ajax的beforeSend方法
2016/01/20 Javascript
纯js实现手风琴效果
2020/04/17 Javascript
浅析JavaScript中命名空间namespace模式
2016/06/22 Javascript
使用 Node.js 对文本内容分词和关键词抽取
2017/05/27 Javascript
详解React服务端渲染从入门到精通
2019/03/28 Javascript
Vue父组件如何获取子组件中的变量
2019/07/24 Javascript
有趣的JavaScript隐式类型转换操作实例分析
2020/05/02 Javascript
手把手教你实现 Promise的使用方法
2020/09/02 Javascript
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
[59:08]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第一局
2016/02/27 DOTA
[04:54]DOTA2-DPC中国联赛1月31日Recap集锦
2021/03/11 DOTA
python获取标准北京时间的方法
2015/03/24 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
2015/05/20 Python
Python3之乱码\xe6\x97\xa0\xe6\xb3\x95处理方式
2020/05/11 Python
解析python 类方法、对象方法、静态方法
2020/08/15 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
通过css3的filter滤镜改变png图片的颜色的示例代码
2020/05/06 HTML / CSS
HTML5拖放效果的实现代码
2016/11/17 HTML / CSS
世界领先的艺术图书出版社:TASCHEN
2018/07/23 全球购物
机械设计制造专业个人求职信
2013/09/25 职场文书
函授毕业自我鉴定
2014/02/04 职场文书
暑期研修感言
2014/02/17 职场文书
2014年社区庆元旦活动方案
2014/03/08 职场文书
房地产公司见习自我鉴定
2014/04/28 职场文书
大班亲子运动会方案
2014/06/10 职场文书
五一活动标语
2014/06/30 职场文书
校友回访母校寄语
2015/02/26 职场文书