2013-11-03 123 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

相關問題