Python 当转换为大写/小写时,字符串会变短吗?

Python 当转换为大写/小写时,字符串会变短吗?,python,string,python-3.x,unicode,Python,String,Python 3.x,Unicode,当转换为大写或小写时,字符串可能会变长(以Unicode代码点表示)。例如,'ß'.upper()的计算结果为'SS'。但是否有字符串变短了?也就是说,是否存在字符串s,使得表达式 len(s.lower()) < len(s) or len(s.upper()) < len(s) len(s.lower())

当转换为大写或小写时,字符串可能会变长(以Unicode代码点表示)。例如,
'ß'.upper()
的计算结果为
'SS'
。但是否有字符串变短了?也就是说,是否存在字符串
s
,使得表达式

len(s.lower()) < len(s) or len(s.upper()) < len(s)
len(s.lower())

计算结果为
True

我认为这可能取决于实现。我将根据CPython的来源来回答

在我看来,在两种可能的情况下,对字符串调用
lower
可以缩短字符串

  • 相邻的两个Unicode点的某些组合将转换为一个Unicode点
  • 单个Unicode点被转换为空字符串
  • 我们可以通过检查内部小写转换函数的类型签名来确定案例1是否可行。在这里

    看起来案例2也被破获了

    我们也可以将上述逻辑应用于
    上层
    。对于情况1,
    \u PyUnicode\u ToUpperFull
    的实现几乎与其较低的对应项相同;对于情况2,相应的列表理解同样返回一个空列表

    结论
    不,
    lower
    upper
    永远不要缩短任何长度。

    您需要创建一个循环来找到答案。只需为每个Unicode字符尝试以下表达式,然后将每次迭代的表达式值设置为布尔值。@geekpradd有110万个Unicode字符,因此这是10^12个可能的2字符组合:需要花费相当长的时间来测试它们。请问您为什么想知道这些?您需要什么样的实现?还是你只想获得声誉积分?确实有很多unicode字符,但只有
    .upper
    .lower
    才能解释其中的一小部分。我知道,但这是找到这个不合逻辑问题答案的唯一方法。我认为没有人知道这个问题的答案(即使是发布这项工作的unicode开发人员也不知道)。根据算法的不同,110万次迭代可能不需要那么长的时间。也许我应该直接问我更复杂的问题,而不是冒出现x/y问题的风险。顺便说一句,
    lower
    可以使字符串变长。特别是,
    U+0130拉丁文大写字母I加上上面的点
    变成了一个常规的ascii“I”加上
    U+0307加上上面的点
    。我还应该指出,它看起来确实像是
    \U PyUnicode\U ToLowerFull
    能够返回零长度字符串,只是对于我的特定语言环境,它似乎从来没有这样做过。如果Python发行版的
    unicodetype_db.h
    文件不同,则可能会产生不同的结果。所以是 啊重申“取决于执行”。
    int _PyUnicode_ToLowerFull(Py_UCS4 ch, Py_UCS4 *res)
    {
        const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
    
        if (ctype->flags & EXTENDED_CASE_MASK) {
            int index = ctype->lower & 0xFFFF;
            int n = ctype->lower >> 24;
            int i;
            for (i = 0; i < n; i++)
                res[i] = _PyUnicode_ExtendedCase[index + i];
            return n;
        }
        res[0] = ch + ctype->lower;
        return 1;
    }
    
    >>> import sys
    >>> unicode_chars = list(map(chr, range(sys.maxunicode+1)))
    >>> [x for x in unicode_chars if len(x.lower()) == 0]
    []