2011-01-07 78 views
1

我在將字符映射到字典時遇到了一些問題。我所去的是創建使用映射和範圍映射ascii字符的字典

counter = { '!': 0, '"': 0, '#': 0, '$': 0 } ... 

對於小數的所有ASCII字符範圍

range(33,64) range(91,96) and range(123,126) 

一段時間後,我發現,地圖可能被用來傳遞CHR的功能和名單從返回範圍迭代...

symbolMap = map(chr, range(33,64) + range (91,96) + range(123,126)) 

的問題是,這個地圖不corrospond到ASCII表,當我嘗試

事情變得更糟糕
counter = dict.fromkeys(symbolMap, 0) 

看到我的shell會話:

>>> counter 
{'!': 0, '#': 0, '"': 0, '%': 0, '$': 0, "'": 0, '&': 0, ')': 0, '(': 0, '+': 0, '*': 0, '-': 0, ',': 0, '/': 0, '.': 0, '1': 0, '0': 0, '3': 0, '2': 0, '5': 0, '4': 0, '7': 0, '6': 0, '9': 0, '8': 0, ';': 0, ':': 0, '=': 0, '<': 0, '?': 0, '>': 0, '[': 0, ']': 0, '\\': 0, '_': 0, '^': 0, '{': 0, '}': 0, '|': 0} 
>>> chr(34) 
'"' 
>>> range(33,64) 
[33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] 
>>> symbolMap 
['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '[', '\\', ']', '^', '_', '{', '|', '}'] 

有人能向我解釋如何解決這一問題,以便它正確地映射出來。

+2

我想我沒有讀好你的問題,因爲我不知道你的問題是什麼。您發佈的代碼顯示您所需的輸出。你是否因爲命令不正確而被拋出? `字典沒有秩序。 – aaronasterling 2011-01-07 07:05:37

+1

「計數器」中包含的內容不應該是什麼? 「計數器」中應該包含哪些不是? – 2011-01-07 08:27:24

+0

如果您想要的代碼應該是數字和標點符號,請查看string.punctuation和string.digits。 – 2011-01-07 18:01:24

回答

3

打印字典時的順序不是按鍵的值,也不是必須的。順序取決於您正在運行的Python的實現,在CPython上,順序取決於密鑰的哈希值和插入順序。

對於所有意圖和目的,您應該假定訂單是隨機的。

換句話說:您的代碼有效!

>>> symbol_map = dict([(chr(x), x) for x in range(33,64) + range (91,96) + range(123,126)]) 
>>> symbol_map 
{'!': 33, '#': 35, '"': 34, '%': 37, '$': 36, "'": 39, '&': 38, ')': 41, '(': 40, '+': 43, '*': 42, '-': 45, ',': 44, '/': 47, '.': 46, '1': 49, '0': 48, '3': 51, '2': 50, '5': 53, '4': 52, '7': 55, '6': 54, '9': 57, '8': 56, ';': 59, ':': 58, '=': 61, '<': 60, '?': 63, '>': 62, '[': 91, ']': 93, '\\': 92, '_': 95, '^': 94, '{': 123, '}': 125, '|': 124} 

這裏可以看到,每個字符正確地映射到字符的右側依次:

>>> symbol_map['/'] 
47 

此,如果你用的字符數代替0值更清晰

字典中的順序沒有區別,除非您需要按特定順序將其打印出來。在這種情況下,你可以做到這一點通過排序:

>>> for x in sorted(symbol_map): print x, 
... 
! " # $ % & ' () * + , - ./0 1 2 3 4 5 6 7 8 9 : ; <=> ? [ \ ]^_ { | } 

但是,當使用它,你通常不需要字典都被歸類爲您重點訪問的目錄。

更新:我想這些具體的範圍是故意的,但如果你想在一般的標點符號和數字,試試這個:

>>> import string 
>>> symbol_map = dict([(x, 0) for x in string.punctuation + string.digits]) 
>>> symbol_map.keys() 
['!', '#', '"', '%', '$', "'", '&', ')', '(', '+', '*', '-', ',', '/', '.', '1', '0', '3', '2', '5', '4', '7', '6', '9', '8', ';', ':', '=', '<', '?', '>', '@', '[', ']', '\\', '_', '^', '`', '{', '}', '|', '~'] 

從你的是未成年人的區別,它包括~例如,但仍。

3

我會做類似

>>> codes = range(33,64) + range (91,96) + range(123,126) 
>>> counter = dict((chr(c), 0) for c in codes) 
>>> counter 
{'!': 0, '#': 0, '"': 0, '%': 0, '$': 0, "'": 0, '&': 0, ')': 0, '(': 0, '+': 0, '*': 0, 
'-': 0, ',': 0, '/': 0, '.': 0, '1': 0, '0': 0, '3': 0, '2': 0, '5': 0, '4': 0, '7': 0, 
'6': 0, '9': 0, '8': 0, ';': 0, ':': 0, '=': 0, '<': 0, '?': 0, '>': 0, '[': 0, ']': 0, 
'\\': 0, '_': 0, '^': 0, '{': 0, '}': 0, '|': 0} 

這只是傳遞的元組的構造函數dict類的序列。每個元組的第一個元素是你想要在地圖中的一個字符,第二個元素是0.

值得注意的是,這會產生相同的輸出結果,您在問題中請求的字符串順序無序。你已經得到了這個輸出,你的方式可能稍微快一點,但對於這個大小的字典,這並不重要。發生器表達式通常優於map,使用dict構造函數比dict.fromkeys更具規範性。我所展示的方式讓我更加清楚地表達了自己的意圖。儘管如此,我不確定你的問題到底是什麼。

0

您可以使用在Python 2.7中添加的collections模塊中的OrderedDict字典子類來保留鍵的插入順序。這隻影響字典顯示自身的方式,所有其他操作與常規字典相同。使用它可以讓你更清楚地看到它的內容(但工作原理與你所做的一樣)。

>>> symbolMap = map(chr, range(33,64) + range (91,96) + range(123,126)) 
>>> symbolMap 
['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', 
'/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', 
'=', '>', '?', '[', '\\', ']', '^', '_', '{', '|', '}'] 
>>> from collections import OrderedDict 
>>> counter = OrderedDict((chr(c),0) for c in range(33,64) + range(91,96) + range(123,126)) 
>>> counter 
OrderedDict([('!', 0), ('"', 0), ('#', 0), ('$', 0), ('%', 0), ('&', 0), 
("'", 0), ('(', 0), (')', 0), ('*', 0), ('+', 0), (',', 0), ('-', 0), 
('.', 0), ('/', 0), ('0', 0), ('1', 0), ('2', 0), ('3', 0), ('4', 0), 
('5', 0), ('6', 0), ('7', 0), ('8', 0), ('9', 0), (':', 0), (';', 0), 
('<', 0), ('=', 0), ('>', 0), ('?', 0), ('[', 0), ('\\', 0), (']', 0), 
('^', 0), ('_', 0), ('{', 0), ('|', 0), ('}', 0)]) 
>>> counter['#'] = counter['#']+1 
>>> counter 
OrderedDict([('!', 0), ('"', 0), ('#', 1), ('$', 0), ('%', 0), ('&', 0), 
("'", 0), ('(', 0), (')', 0), ('*', 0), ('+', 0), (',', 0), ('-', 0), 
('.', 0), ('/', 0), ('0', 0), ('1', 0), ('2', 0), ('3', 0), ('4', 0), 
('5', 0), ('6', 0), ('7', 0), ('8', 0), ('9', 0), (':', 0), (';', 0), 
('<', 0), ('=', 0), ('>', 0), ('?', 0), ('[', 0), ('\\', 0), (']', 0), 
('^', 0), ('_', 0), ('{', 0), ('|', 0), ('}', 0)]) 

你真的不說你想要的字典,但是從它的名字和內容,它看起來像你想指望某些字符的發生。在Python 2.7中,collections模塊還有另一個名爲Counter的新類,專門用於該目的。以下是如何使用它:

>>> from collections import Counter 
>>> counts = Counter('%hello%; world!') 
>>> counts 
Counter({'l': 3, '%': 2, 'o': 2, '!': 1, ' ': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1, 'e': 1, ';': 1}) 
>>> chars = [chr(c) for c in range(33,64) + range(91,96) + range(123,126)] 
>>> for c in chars: 
...  if c in counts: 
...    print repr(c), counts[c] 
... 
'!' 1 
'%' 2 
';' 1