2013-11-03 194 views
2

我想用HTML实体替换特殊字符,但结果是随机的相同的输入,我不明白为什么。功能不会返回每次运行相同的结果

下面是代码:

def secure(text): 
    hsconvert = {"\'": "\\'", "\"": "\\\"", "¢": "&cent;", "©": "&copy;", "÷": "&divide;", ">": "&gt;", "<": "&lt;", "µ": "&micro;", "·": "&middot;", "¶": "&para;", "±": "&plusmn;", "€": "&euro;", "£": "&pound;", "®": "&reg;", "§": "&sect;", "™": "&trade;", "¥": "&yen;", "á": "&aacute;", "Á": "&Aacute;", "à": "&agrave;", "À": "&Agrave;", "â": "&acirc;", "Â": "&Acirc;", "å": "&aring;", "Å": "&Aring;", "ã": "&atilde;", "Ã": "&Atilde;", "ä": "&auml;", "Ä": "&Auml;", "æ": "&aelig;", "Æ": "&AElig;", "ç": "&ccedil;", "Ç": "&Ccedil;", "é": "&eacute;", "É": "&Eacute;", "è": "&egrave;", "È": "&Egrave;", "ê": "&ecirc;", "Ê": "&Ecirc;", "ë": "&euml;", "Ë": "&Euml;", "í": "&iacute;", "Í": "&Iacute;", "ì": "&igrave;", "Ì": "&Igrave;", "î": "&icirc;", "Î": "&Icirc;", "ï": "&iuml;", "Ï": "&Iuml;", "ñ": "&ntilde;", "Ñ": "&Ntilde;", "ó": "&oacute;", "Ó": "&Oacute;", "ò": "&ograve;", "Ò": "&Ograve;", "ô": "&ocirc;", "Ô": "&Ocirc;", "ø": "&oslash;", "Ø": "&Oslash;", "õ": "&otilde;", "Õ": "&Otilde;", "ö": "&ouml;", "Ö": "&Ouml;", "ß": "&szlig;", "ú": "&uacute;", "Ú": "&Uacute;", "ù": "&ugrave;", "Ù": "&Ugrave;", "û": "&ucirc;", "Û": "&Ucirc;", "ü": "&uuml;", "Ü": "&Uuml;", "ÿ": "&yuml;", "\\":"\\\\"}; 
    for i, j in hsconvert.items(): 
     text = text.replace(i, j) 
     return text 

print(secure("La Vie d'Adèle, chapitres 1 & 2")) 

下面是控制台输出:

>>> ================================ RESTART ================================ 
>>> 
La Vie d\'Ad&egrave;le, chapitres 1 & 2 
['TV Movie', 'Video Game', 'TV Episode', 'TV Series', 'TV Series ', 'Short', 'TV Mini-Series'] 
>>> ================================ RESTART ================================ 
>>> 
La Vie d\\'Ad&egrave;le, chapitres 1 & 2 
['TV Movie', 'Video Game', 'TV Episode', 'TV Series', 'TV Series ', 'Short', 'TV Mini-Series'] 

问题是与其有时返回\'和有时\\''字符。

我认为它来自字典中的最后一项,"\\":"\\\\",但我不明白为什么它在每次运行时不会被解释为相同。

回答

3

正如你在你的答案中推测的那样,问题是对字典的迭代没有定义的顺序。

Python 3 documentation

表演名单(运行起来也())上的字典返回字典中使用的所有 键,以任意顺序列表(如果你想让它 排序,只是使用排序(d.keys()))。

它没有明确说明,但同样适用于items()。

在这种情况下,我有点惊讶地发现迭代之间的顺序变化,但在这种情况下,任意意味着未定义 - 任何顺序在技术上都是有效的。如果你想得到一致的结果,我建议重新设计你的算法,不要对项目的顺序敏感;否则,首先对输出进行排序或使用OrderedDict至少可以解决一致性问题。

0

我已经修改了功能如下,它是工作:

def secure(text): 
    text.replace("\\", "\\\\") 
    hsconvert = {"\'": "\\'", "\"": "\\\"", "¢": "&cent;", "©": "&copy;", "÷": "&divide;", ">": "&gt;", "<": "&lt;", "µ": "&micro;", "·": "&middot;", "¶": "&para;", "±": "&plusmn;", "€": "&euro;", "£": "&pound;", "®": "&reg;", "§": "&sect;", "™": "&trade;", "¥": "&yen;", "á": "&aacute;", "Á": "&Aacute;", "à": "&agrave;", "À": "&Agrave;", "â": "&acirc;", "Â": "&Acirc;", "å": "&aring;", "Å": "&Aring;", "ã": "&atilde;", "Ã": "&Atilde;", "ä": "&auml;", "Ä": "&Auml;", "æ": "&aelig;", "Æ": "&AElig;", "ç": "&ccedil;", "Ç": "&Ccedil;", "é": "&eacute;", "É": "&Eacute;", "è": "&egrave;", "È": "&Egrave;", "ê": "&ecirc;", "Ê": "&Ecirc;", "ë": "&euml;", "Ë": "&Euml;", "í": "&iacute;", "Í": "&Iacute;", "ì": "&igrave;", "Ì": "&Igrave;", "î": "&icirc;", "Î": "&Icirc;", "ï": "&iuml;", "Ï": "&Iuml;", "ñ": "&ntilde;", "Ñ": "&Ntilde;", "ó": "&oacute;", "Ó": "&Oacute;", "ò": "&ograve;", "Ò": "&Ograve;", "ô": "&ocirc;", "Ô": "&Ocirc;", "ø": "&oslash;", "Ø": "&Oslash;", "õ": "&otilde;", "Õ": "&Otilde;", "ö": "&ouml;", "Ö": "&Ouml;", "ß": "&szlig;", "ú": "&uacute;", "Ú": "&Uacute;", "ù": "&ugrave;", "Ù": "&Ugrave;", "û": "&ucirc;", "Û": "&Ucirc;", "ü": "&uuml;", "Ü": "&Uuml;", "ÿ": "&yuml;"}; 
    for i, j in hsconvert.items(): 
     text = text.replace(i, j) 
    return text 

,但我不明白为什么老功能无法正常工作......一种在... X并不总是同样的顺序?

+3

也许你可以使它更明显_exactly_你的修改是什么以及为什么你认为它解决了问题,即使你不知道是什么导致旧的失败?附:字典没有订单,这意味着替换正在以随机顺序进行评估...... – Ben

+0

我认为你只是回答了这个问题......我认为for是有序的,但它似乎是有序的,因此如果替换起初是在第一次两次后结果不同!!! – user1998000

+0

订购'for'。这是字典是不是(正如我在我的答案解释!) – rlms

0

有时候,您的代码首先用\\\\代替\\,然后\'\\'代替。有时候它会反过来。

例子(使用 “\'” 作为输入):

如果我们这样做\\ - >\\\\,然后再\' - >\\'我们得到\'的第一次尝试更换(这里什么都不会发生,因为有ISN后“第二个后面是),然后是\\'

但是,如果我们做到这一点反过来,我们得到\\'后的第一个,然后将其替换\\\\\\第二,所以我们最终\\\\'

发生这种情况是因为hsconvert是一个字典,所以它没有排序,并且遍历它(for循环)不一定每次都以相同的方式发生。

你解决问题的方法很好,但为了将来的参考,collections模块中有一个OrderedDict

相关问题