当前位置:首页>python>当 Python 遇见诗仙李白:1000多首唐诗里藏着什么高频密码?

当 Python 遇见诗仙李白:1000多首唐诗里藏着什么高频密码?

  • 2026-10-11 05:39:04
当 Python 遇见诗仙李白:1000多首唐诗里藏着什么高频密码?
李白一生写了有1000多首诗,在我们记忆的深处,李白总是与“白发三千丈”的夸张、“天生我材必有用”的狂傲以及“举杯邀明月”的潇洒联系在一起。然而,当这位“诗仙”走下神坛,他的文字在计算机的客观审视下,又会呈现出怎样的面貌?
今天,作为《代码里的人文》系列的第一期,我们用Python 代码对《全唐诗》中收 录的李白诗歌进行数字化文本分析。让我们剥离感性的刻板印象,用数据解构这位浪漫主义灵魂背后的“核心高频密码”。
📝第一步:数据获取,搬出大唐“诗词库”
要用代码解构李白的诗,首先得有源头活水。这里我们借助了 GitHub 上著名开源项目 chinese-poetry (最全中华古诗词数据库)。

我选择其中的“全唐诗”下载,根据命名规则可以看出来,代表唐诗的JSON文件名格式如下:poet.tang.*.json,因此,我们可以拷贝出所有的唐诗。打开其中一个JSON文件,我们可以看到里面的存储结构:

{        "author": "李白",        "paragraphs": [            "金樽清酒斗十千,玉盤珍羞直萬錢。",            "停杯投筯不能食,拔劒四顧心茫然。",            "欲渡黃河冰塞川,將登太行雪滿山。",            "閑來垂釣碧溪上,忽復乘舟夢日邊。",            "行路難,行路難,多岐路,今安在。",            "長風破浪會有時,直挂雲帆濟滄海。"        ],        "tags": [            "唐诗三百首",            "黄河",            "励志",            "友情",            "八年级下册(课内)",            "初中古诗",            "乐府",            "宴饮",            "哲理",            "怀才不遇"        ],        "title": "行路難三首 一",        "id": "c348bc2e-f50d-436b-88b7-c198d63dacfc"}

其中,author代表作者名,paragraphs代表诗歌具体内容,tags代表诗歌的标签以及情感,title代表诗名,id是一个序列号。

接下来,我们编写一段 Python 脚本。为了避免繁简转换导致的统计误差,我们引入了 OpenCC 进行繁简统一,把李白的诗歌全部筛选并提取出来:

def load_li_bai_poems():    """加载所有李白诗歌"""    all_poems = []    json_files = glob.glob(os.path.join(TANG_POETRY_DIR, 'poet.tang.*.json'))    print(f"找到 {len(json_files)} 个唐诗JSON文件")    for json_file in json_files:        with open(json_file, 'r', encoding='utf-8') as f:            poems = json.load(f)            for poem in poems:                # 转换繁体为简体后比较                author = cc.convert(poem.get('author', ''))                if author == '李白':                    # 转换诗歌内容为简体                    paragraphs = [cc.convert(p) for p in poem.get('paragraphs', [])]                    title = cc.convert(poem.get('title', ''))                    tags = [cc.convert(t) for t in poem.get('tags', [])]                    all_poems.append({                        'title': title,                        'paragraphs': paragraphs,                        'tags': tags                    })    print(f"共找到 {len(all_poems)} 首李白的诗歌")    return all_poems

🧠第二步:自然语言处理,属于算法的“归一化”浪漫

拿到了诗歌文本,该如何分析李白最爱写什么?

这里我提取李白写的最多的十个名词,因为名词可以更好的表达出李白写的内容,其余的语气词和助词无法表现出李白所描述的主要内容。名词的切分主要使用 Python 著名的 NLP 工具包 jieba 。

我们还可以把一些自定义的词作为名词给出,这样,当程序识别到我们自定义的词后会将其认为是名词,如:“月”、“风”、“山”、“水”、“云”、“天”等。

这里还有一个要注意的地方,因为”明月“、”皓月“、”江月“、”新月“等等都是”月“,如果都按每个名词统计的话,单字“月”出现的次数会大大减少,无法还原诗人脑海中真实描绘的意象。

因此,我们在使用 jieba 进行分词提取名词的同时,必须建立一套“意象归一化(Normalization)规则”:

核心思想:我们将自然语言处理中的“同义词合并”思想注入古典文学,自定义了一个意象映射字典,如:

【月相关】:明月、皓月、月色、月光、皎月 → 月

【山相关】:青山、碧山、苍山、远山 → 山

【酒相关】:美酒、清酒、浊酒、芳酒 → 酒

【天相关】:青天、蓝天、苍天、碧天 → 天

# 定义归一化规则normalization_rules = {        # 月相关        '明月': '月', '皓月': '月', '皎月': '月', '新月': '月', '满月': '月',        '月色': '月', '月光': '月', '月华': '月', '月明': '月',        # 天相关        '青天': '天', '蓝天': '天', '碧天': '天', '苍天': '天', '九天': '天',        '天空': '天', '天际': '天',        # 云相关        '白云': '云', '浮云': '云', '青云': '云', '乌云': '云', '彩云': '云',        '云彩': '云', '行云': '云', '闲云': '云',        # 山相关        '青山': '山', '碧山': '山', '苍山': '山', '秀山': '山', '寒山': '山',        '远山': '山', '群山': '山', '山河': '山',        # 水相关        '绿水': '水', '碧水': '水', '清水': '水', '江水': '水', '河水': '水',        '湖水': '水', '泉水': '水', '海水': '水', '溪水': '水',        # 风相关        '春风': '风', '秋风': '风', '西风': '风', '东风': '风', '北风': '风',        '南风': '风', '寒风': '风', '暖风': '风', '微风': '风', '长风': '风',        # 花相关        '桃花': '花', '梅花': '花', '菊花': '花', '兰花': '花', '桂花': '花',        '杏花': '花', '荷花': '花', '梨花': '花', '百花': '花', '春花': '花',        # 鹤相关        '白鹤': '鹤', '黄鹤': '鹤', '仙鹤': '鹤', '孤鹤': '鹤', '云鹤': '鹤',        # 酒相关        '美酒': '酒', '清酒': '酒', '浊酒': '酒', '浊酒': '酒', '芳酒': '酒',        # 人相关        '美人': '人', '故人': '人', '新人': '人', '人人': '人', '世人': '人',        '诗人': '人', '骚人': '人', '游子': '人', '征夫': '人', '思妇': '人',        # 鸟相关        '黄鹂': '鸟', '黄鸟': '鸟', '白鹭': '鸟', '飞鸟': '鸟', '百鸟': '鸟',        '啼鸟': '鸟', '宿鸟': '鸟', '归鸟': '鸟',        # 树相关        '绿树': '树', '青树': '树', '碧树': '树', '古树': '树', '老树': '树',        # 草相关        '芳草': '草', '青草': '草', '绿草': '草', '春草': '草', '细草': '草',        # 路相关        '长路': '路', '道路': '路', '路途': '路', '陌路': '路', '歧路': '路',}          
同时,我们在代码中过滤掉了无意义的代词、介词和助词(如:我、你、之、于、与、和、而、以、为 等),只保留含金量最高的“名词”。
def extract_nouns(text, custom_dict_set):    """从文本中提取名词"""    words = pseg.cut(text)    nouns = []    for word, flag in words:        # 提取名词 (n开头的词性标记) 或在我们的自定义词典中        if flag.startswith('n') or word in custom_dict_set:            if len(word) == 1 and word in ['我', '你', '他', '她', '它', '此', '其', '之', '于', '与', '和', '而', '以', '为']:                continue            # 过滤单字标点和数字            if len(word) >= 1 and not word.isdigit():                nouns.append(word)    return nouns
📊第三步:数据说话,李白 vs 杜甫

提取出名词后,我们需要对名词进行归一化,最后进行统计,看看是哪个类型的词最多。

def analyze_nouns(poems):    """分析诗歌中的名词"""    # 初始化jieba加载自定义词典    for line in custom_dict.strip().split('\n'):        if line.strip():            word = line.strip().split()[0]  # 只取词语部分            jieba.add_word(word, freq=100, tag='n')    # 构建自定义词典集合    custom_set = set()    for line in custom_dict.strip().split('\n'):        word = line.strip()        if word:            custom_set.add(word)    all_nouns = []    for poem in poems:        # 合并所有诗句        text = ''.join(poem['paragraphs'])        # 提取诗歌中的名词        nouns = extract_nouns(text, custom_set)        all_nouns.extend(nouns)    # 归一化处理,把同类的名词都算成是一类    normalized_nouns = normalize_nouns(all_nouns)    # 统计词频    noun_counts = Counter(normalized_nouns)    return noun_counts

最后,我们通过柱状图和词云来展示到底最多的十个词是什么,我们可以期待一下😀

通过对李白诗歌名词的统计,排名前十的高频词依次是:

 人 → 云 → 水 → 君 → 风 → 时 → 月 → 山 → 酒 → 春 

除去“人”、“君”、“时”等社会属性词汇外,李白宇宙的核心是由“云、水、风、月、山、酒、 春”构成的。这简直是一幅完美的中国山水写意画。他的生性豁达与大度,在这些与自然、美酒交融的词汇中得到了完美的数字化印证。真正走入他内心的核心意象,莫过于“月”、“山”、“酒”。

我们还可以对以上程序进行修改,只要将author改成“杜甫”,我们就可以看到杜甫的诗歌中频率最高的几个词。

当我们把统计范围放宽到前 20 个高频词时,属于“诗圣”杜甫的词频特征呈现出了完全不同的生命质感。在杜甫的诗中,除了同样高频的“人”和自然意象外,极其刺眼地闪现出 了“客”、“鸟”、“舟”、“气”、“病”、“事”、“花”等词汇: 

“客”:是颠沛流离、寄人篱下的羁旅之苦。 

“舟”:是老病孤舟、漂泊无依的现实写照。

 “病”与“气”:更是直接暴露出这位忧国忧民的伟大诗人,在晚年身体与精神上承受的沉重苦难。 

同样活在大唐,李白的代码输出是一场“风月与美酒”的太空漫游;而杜甫的代码输出,则是“老病与羁旅”的现实大地。

✍四、结论:当人文有了数字的刻度

从冰冷的数据和严格的代码中,我们没有破坏诗歌的意境,反而通过可视化的坐标,更深地读懂了他们的灵魂。李白之所以是“诗仙”,是因为他的高频词里藏着不属于凡间的“云、风、月、酒”。他的浪漫与豪放,不仅仅是文学选集的粉饰,更是他一生真真切切、高频重复的生命体验。

下一篇我们将来看一看李白的诗歌的情感色彩是怎样的,以及他与杜甫的内心情感差别有多大。

最新文章

随机文章