2013-02-19 90 views
1

考慮以下幾點:的Python:複製重複字典到列表 - 最後一個字典項上當受騙到所有列表項

import re 
sequence = 'FFFFFF{7}FFFFFF' 
patterns = [ ('([0-9a-fA-F]+)', 'Sequence'), 
    ('(\\([0-9a-fA-F]+\\|[0-9a-fA-F]+\\))', 'Option'), 
    ('({[0-9a-fA-F]+})', 'Range'), 
    ('(\\[[0-9a-fA-F]+:([0-9a-fA-F]+|\*)\\])', 'Slice'), 
    ('(\\?\\?)+', 'Byte_value_Wildcard'), 
    ('(\\*)+', 'Byte_length_wildcard') ] 
fragment_counter = 0 
fragment_dict= {} 
fragments_list = [] 
while sequence: 
    found = False 
    for pattern, name in patterns: 
     m = re.match (pattern,sequence) 
     if m: 
      fragment_counter+=1 
      m = m.groups() [0] 
      fragment_dict["index"]=fragment_counter 
      fragment_dict["fragment_type"]=name 
      fragment_dict["value"]=m 
      print fragment_dict 
      fragments_list.append(fragment_dict) 
      sequence = sequence [len (m):] 
      found = True 
      break 
    if not found: raise Exception ('Unrecognized sequence') 

print fragments_list 

每次點擊「打印fragment_dict」線時間,我得到正確的(預期)輸出:

{'index': 1, 'fragment_type': 'Sequence', 'value': 'FFFFFF'} 
{'index': 2, 'fragment_type': 'Range', 'value': '{7}'} 
{'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'} 

然而,列表項fragments_list是最終字典的3份,不每條線作爲我期望:

[{'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}, {'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}, {'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}] 

我假設這是因爲append引用字典的實例,而不是複製字典的每個迭代。我看着使用list()函數,但在字典項目,它只是給了我一個字典鍵列表。

我在做什麼錯?
我並不喜歡數據類型,我只需要一種方法來爲每個我找到的片段保存3個數據元素(也許是第4個)。

回答

1

很高興見到你實際上是用我的答案的代碼到你的最後一個問題。當我的答案確實有幫助時,我總是很開心。

考慮到,在你前面的問題,你說,這個分​​析僅僅是熱身後處理分析令牌,你可能會考慮這一點:

你有每個令牌類型創建一個類。在每個內部實現一個process方法,這將有時做實際處理(而不是我在下面的代碼中做的狼,軸承,狐狸和獾)。

然後解析與Stream類全碼流播放。您可以通過Stream.tokens迭代令牌,並且可以通過調用Stream.process來處理包含的所有令牌。

你把這些類放在一個python文件中,將它導入你的主代碼,你只需要創建一個Stream的實例來解析它並處理它。

事情是這樣的:

#! /usr/bin/python3.2 

import re 

class Sequence: 
    def __init__ (self, raw): self.__raw = raw 
    def __str__ (self): return 'Sequence {}'.format (self.__raw) 
    def process (self): print ('Wolfing sequence {}'.format (self.__raw)) 

class Option: 
    def __init__ (self, raw): self.__raw = raw 
    def __str__ (self): return 'Option {}'.format (self.__raw) 
    def process (self): print ('Foxing option {}'.format (self.__raw)) 

class Range: 
    def __init__ (self, raw): self.__raw = raw 
    def __str__ (self): return 'Range {}'.format (self.__raw) 
    def process (self): print ('Bearing range {}'.format (self.__raw)) 

class Slice: 
    def __init__ (self, raw): self.__raw = raw 
    def __str__ (self): return 'Slice {}'.format (self.__raw) 
    def process (self): print ('Badgering slice {}'.format (self.__raw)) 


class Stream: 
    patterns = [ ('([0-9a-fA-F]+)', Sequence), 
     ('(\\([0-9a-fA-F]+\\|[0-9a-fA-F]+\\))', Option), 
     ('({[0-9a-fA-F]+})', Range), 
     ('(\\[[0-9a-fA-F]+:[0-9a-fA-F]+\\])', Slice) ] 

    def __init__ (self, stream): 
     self.__tokens = [] 
     while stream: 
      found = False 
      for pattern, cls in self.patterns: 
       m = re.match (pattern, stream) 
       if m: 
        m = m.groups() [0] 
        self.__tokens.append (cls (m)) 
        stream = stream [len (m):] 
        found = True 
        break 
      if not found: raise Exception ('Unrecognized sequence') 

    @property 
    def tokens (self): return (token for token in self.__tokens) 

    def process (self): 
     for token in self.__tokens: token.process() 

stream = Stream ('524946(46|58){4}434452[22:33]367672736E') 
print ('These are the tokens:') 
for idx, token in enumerate (stream.tokens): 
    print ('{} at position {}.'.format (token, idx)) 

print ('\nNow let\'s process them all:') 
stream.process() 

這產生了:

These are the tokens: 
Sequence 524946 at position 0. 
Option (46|58) at position 1. 
Range {4} at position 2. 
Sequence 434452 at position 3. 
Slice [22:33] at position 4. 
Sequence 367672736E at position 5. 

Now let's process them all: 
Wolfing sequence 524946 
Foxing option (46|58) 
Bearing range {4} 
Wolfing sequence 434452 
Badgering slice [22:33] 
Wolfing sequence 367672736E 
+0

嘿,這太棒了,謝謝!我的下一個磚牆正面臨着我,我懷疑你的修改過的方法將幫助我適當地瀏覽結果數據對象。我會實現,然後看看我能做什麼,但基本上,下一個任務是能夠基於某種邏輯爲每個序列提取片段實體 - (例如哪個片段實體具有最大的len(),它的索引是什麼)。我確信我很快會回來問問題,但是再次感謝您的意見,這非常有用!既解決手頭的問題,又看到有經驗的用戶如何解決問題! – 2013-02-19 23:13:50

+0

它可能非常反對這裏的事情,但我想再次感謝你的幫助。花了一些時間把它放在一起,你的代碼是完美的,很容易(1)看到正在發生的事情和(2)與之合作。它可以完全像我想象的那樣執行。我荒謬的讚賞! – 2013-02-20 19:26:52

+1

不客氣,我很樂意提供幫助。一旦你設定好了,我也很樂意同行評審你的代碼。人們總是可以相互學習一點。不幸的是,SO不允許私人信息,但如果您可以在此留下電子郵件地址,我會與您聯繫,以防您希望進行同行評審。 – Hyperboreus 2013-02-20 20:55:18

3

你非常接近。代替list()功能,其產生從任何序列的新的list(在這種情況下,一個dict作爲序列是其密鑰的序列),使用dict()功能,它從任何映射生成新的dict

或者,也許更簡單,只需使用copy方法。

或者,更簡單地說,只需將fragment_dict= {}移到循環中,即可構建新的dict,而不是繼續重複使用同一個。

+0

那麼簡單。事實上,我應該剛剛測試'字典'!謝謝。讚賞。 – 2013-02-19 01:54:00

+2

@JayGattuso:這是那種一旦你知道它就顯而易見的事情,但在你做之前並沒有太多...... – abarnert 2013-02-19 01:54:54