How pypinyin heteronym=False Generates Deterministic Pinyin Annotations

Setting heteronym=False in pypinyin forces the library to return only the first pronunciation for each Chinese character, eliminating alternative readings required for consistent RIME dictionary generation.

The heteronym parameter in pypinyin controls whether polyphonic characters return multiple pronunciations. In the amzxyz/rime-lmdg repository, which builds input method dictionaries for the RIME framework, this parameter is explicitly disabled to ensure each character maps to exactly one unambiguous pinyin string.

What the heteronym Parameter Controls

According to the pypinyin source code in pypinyin/core.py, the core conversion function defines the parameter as:

def pinyin(self, hans, style=Style.TONE, heteronym=False, errors='default', …)

# :param heteronym: 是否启用多音字

When invoked, the parameter behaves as follows:

  • heteronym=False (default) – Returns only the first pronunciation found in the internal dictionary for each character, producing a flat list structure.
  • heteronym=True – Returns all possible pronunciations as a nested list for characters with multiple readings (heteronyms).

Implementation in the rime-lmdg Repository

The amzxyz/rime-lmdg project explicitly disables heteronym handling to maintain dictionary stability. In wanxiang/wanxiang-tools.py, the conversion logic calls pypinyin with the flag set to False:

py = pypinyin_func(root, style=Style.TONE, heteronym=False, errors='default')
char_py = [p[0] for p in pypinyin_func(word_for_pinyin, style=Style.TONE,
                                      heteronym=False, errors='default')]

This pattern ensures the resulting list contains single string elements rather than nested lists of alternatives. The same approach appears in rime固定或用户词典刷新为带声调编码.py, where pinyin(..., heteronym=False) guarantees one-to-one character-to-pinyin mappings essential for RIME encoding schemes.

Effect on Polyphonic Characters

When processing polyphonic characters (多音字), the heteronym=False setting determines which pronunciation enters the final annotation:

  • (xíng / háng) – Returns "xíng" only, ignoring the banking pronunciation "háng".
  • (zhòng / chóng) – Returns "zhòng" only, omitting the repetition sense "chóng".
  • (le / liǎo) – Returns "le" only, excluding the completion sense "liǎo".

This behavior ensures that building RIME dictionaries with deterministic encoding schemes never creates ambiguous entries where one character maps to multiple code points.

Code Comparison: heteronym=False vs heteronym=True

The practical difference in output structure is demonstrated below:

from pypinyin import pinyin, Style

# With heteronym disabled (default)

pinyin('行', style=Style.TONE, heteronym=False)

# Returns: [['xíng']]

# With heteronym enabled

pinyin('行', style=Style.TONE, heteronym=True)

# Returns: [['xíng', 'háng']]

In the rime-lmdg toolchain, only the first form is used, guaranteeing single-pronunciation annotations that simplify downstream dictionary compilation.

Summary

  • heteronym=False restricts pypinyin output to the primary pronunciation from its internal dictionary, ignoring alternative readings.
  • The amzxyz/rime-lmdg repository relies on this behavior in wanxiang/wanxiang-tools.py and related scripts to generate unambiguous RIME dictionary entries.
  • This setting prevents polyphonic characters from generating multiple pinyin codes, ensuring stable one-to-one mappings between characters and input method encodings.
  • Disabling heteronym handling is critical for deterministic builds where the same character must always resolve to the same phonetic key.

Frequently Asked Questions

What does the heteronym parameter do in pypinyin?

The heteronym parameter controls whether the library returns multiple pronunciations for Chinese characters with several readings. When set to False (the default), pypinyin queries its internal dictionary and returns only the first entry as a single string, whereas True returns a list containing all valid pronunciations for that character.

Why does the rime-lmdg repository set heteronym=False?

The repository builds RIME input method dictionaries that require a single, deterministic pinyin annotation per character to maintain stable encoding schemes. Disabling heteronym handling prevents polyphonic characters from creating ambiguous dictionary entries where one glyph maps to multiple phonetic codes, ensuring consistent key mappings across different generation runs.

How does heteronym=False affect polyphonic characters like 行 or 重?

When heteronym=False, pypinyin returns only the first-listed pronunciation—"xíng" for 行 and "zhòng" for 重—completely ignoring alternative readings such as "háng" (banking) or "chóng" (repetition) that would appear in the output if heteronym handling were enabled.

Can I enable heteronym=True when building RIME dictionaries with this repository?

While technically possible, enabling heteronym support would violate the one-to-one mapping requirement of the RIME dictionary format used by rime-lmdg. The scripts in wanxiang/wanxiang-tools.py specifically extract p[0] (the first element) assuming single-value returns; enabling heteronyms would cause indexing errors and generate invalid dictionary entries with nested lists instead of flat pinyin strings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →