2011-01-07 5 views
1

Ich habe einige Probleme beim Zuordnen von Zeichen zu einem Wörterbuch. Was ich für werde, istErstellen eines Wörterbuchs, das ASCII-Zeichen unter Verwendung der Karte und des Bereichs abbildet

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

Für alle ascii Zeichen im Dezimalsystem

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

Nach einiger Zeit habe ich die Karte möglicherweise verwendet werden, entdeckt könnte chr als Funktion übergeben und die Liste zurück aus für Iterationen Bereich ...

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

Das Problem ist, dass diese Karte nicht in eine ASCII-Tabelle nicht corrospond, und es wird noch schlimmer, wenn ich

versuchen
counter = dict.fromkeys(symbolMap, 0) 

siehe meine Shell-Sitzung:

>>> 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', ':', ';', '<', '=', '>', '?', '[', '\\', ']', '^', '_', '{', '|', '}'] 

Kann jemand mir erklären, wie dieses Problem zu beheben, so dass es korrekt abbildet.

+2

Ich denke, ich habe Ihre Frage nicht gut genug gelesen, da ich keine Ahnung habe, was Ihr Problem ist. Der von Ihnen gepostete Code zeigt Ihre gewünschte Ausgabe an. Bist du geworfen, weil die Reihenfolge nicht stimmt? 'dict's haben keine Ordnung. – aaronasterling

+1

Was ist in 'counter' enthalten, was nicht sein sollte? Was sollte in "Counter" enthalten sein, das ist nicht? –

+0

Wenn die gewünschten Codes im Allgemeinen Zahlen und Interpunktion sein sollen, überprüfen Sie string.punctuation und string.digits. –

Antwort

3

Die Reihenfolge der Wörterbücher, die gedruckt werden, richtet sich nicht nach dem Wert der Schlüssel. Dies muss auch nicht der Fall sein. Die Reihenfolge hängt davon ab, welche Python-Implementierung Sie ausführen. Bei CPython hängt die Reihenfolge vom Hash-Wert des Schlüssels und der Reihenfolge der Einfügung ab.

Für alle Absichten und Zwecke sollten Sie davon ausgehen, dass die Reihenfolge zufällig ist.

Mit anderen Worten: Ihr Code funktioniert!

Dies ist klarer, wenn Sie den Wert 0 mit der Anzahl der Zeichen ersetzen:

>>> 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} 

Hier sehen Sie, dass jedes Zeichen korrekt abbildet nach rechts Ordnungs des Charakters:

>>> symbol_map['/'] 
47 

Die Bestellung im Wörterbuch macht keinen Unterschied, es sei denn, Sie müssen sie in einer bestimmten Reihenfolge ausdrucken. In diesem Fall können Sie das tun durch Sortieren:

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

Aber während es zu benutzen Sie in der Regel tun das Wörterbuch zu sortier nicht benötigen, wie Sie das Verzeichnis von Schlüsseln zugreifen.

Update: dieses Ich dachte, diese spezifischen Bereiche beabsichtigt war, aber wenn Sie Interpunktion und Ziffern im Allgemeinen wollen, versuchen Sie:

>>> 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', ';', ':', '=', '<', '?', '>', '@', '[', ']', '\\', '_', '^', '`', '{', '}', '|', '~'] 

Der Unterschied von Ihnen Moll ist, enthält es ~ zum Beispiel, aber immer noch.

+0

Vielen Dank, Ihr Code für die Zuweisung des Dec-Wertes für jedes Zeichen machte es mir offensichtlich, dass meine Bereiche nicht korrekt für den Symbolsatz waren, den ich wollte, damit ich später in meinem Code die Anzahl für '@' I erhöhen wollte Habe einen Keyerror bekommen, ich habe das Problem dank deiner Arbeitsweise behoben. –

3

würde ich so etwas wie

>>> 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} 

tun Dies geht nur eine Sequenz von Tupeln an den Konstruktor für die dict Klasse. Das erste Element jedes Tupels ist ein Zeichen, das Sie in der Karte und das zweite 0 wünschen.

Es ist erwähnenswert, dass dies die gleiche Ausgabe erzeugt, die Sie in der Frage bis zur Reihenfolge des ungeordneten Wörterbuchs anfordern . Sie erhalten diese Ausgabe bereits und Ihr Weg ist wahrscheinlich etwas schneller, aber für ein Diktat dieser Größe ist das egal. Generatorausdrücke werden im Allgemeinen map vorgezogen und die Verwendung des dict-Konstruktors ist kanonischer als dict.fromkeys. Die Art und Weise, die ich gezeigt habe, kommuniziert die Absicht etwas klarer, glaube ich. Alles in allem bin ich mir nicht sicher, was genau dein Problem ist.

+2

Auch '{chr (c): 0 für c in codes}' (dict-Verständnis) macht dasselbe mit einer besseren Syntax, wenn Sie Python 3 oder 2.7 benutzen. – delnan

0

Mit der OrderedDict Wörterbuch-Unterklasse im collections-Modul, die in Python 2.7 hinzugefügt wurde, können Sie die Reihenfolge der Schlüsseleinfügung beibehalten. Dies wirkt sich nur darauf aus, wie das Wörterbuch angezeigt wird, alle anderen Operationen entsprechen einem regulären Wörterbuch. Wenn Sie es verwenden, können Sie seinen Inhalt klarer sehen (aber arbeiten Sie genauso wie das, was Sie hatten, was OK war).

>>> 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)]) 

Sie sagen nicht wirklich das, was Sie das Wörterbuch wollen, aber aus seinem Namen und Inhalt es sieht aus wie Sie das Auftreten von bestimmten Zeichen zählen möchten. In Python 2.7 hatte das Modul collections auch eine andere neue Klasse namens Counter, die für diesen Zweck entwickelt wurde. Hier ist, wie Sie es verwenden könnten:

Verwandte Themen