2017-07-01 69 views
2

我嘗試重寫下面的代碼使用字典解析工作,只是爲了好玩:嵌套字典解析:太多值解壓

import itertools 

with open('foo.txt') as f: 
    entities = f.read().splitlines() 

parsed_entities = [] 
while entities: 
    props = itertools.takewhile(lambda n: n != 'EOM', entities) 
    entity = {p.split('=')[0]: p.split('=')[1] for p in props} 
    entities = entities[len(entity)+2:] # Delete and skip EOM & newline 
    parsed_entities.append(entity) 

我要替換這一行:

entity = {p.split('=')[0]: p.split('=')[1] for p in props} 

隨着更好看的字典理解,這可能看起來像:

entity = {key: value for p in props for key, value in p.split('=')} 

當我嘗試這樣做,我收到以下錯誤:

ValueError: too many values to unpack (expected 2)

我在做什麼錯?使用ipdb.pm()我看到p是name=yam,這很好,但是keyvalue未定義。因爲這需要p.split()調用的每個結果具有完全相同元素

for key, value in p.split('=') 

+0

我覺得'p.split'('=')的長度不是2. –

+0

@SamChats:當然可以。但'p.split('=')[0]'不是,這就是解壓縮的內容。 –

+0

@SamChats,檢查它。我用'print(len(p.split('=')))'替換了'p.split('=')',它是2. – Infinity

回答

6

你不能做到這一點。相反,你只是有一個單一(字符串)元素序列,長度可變。

你不得不換p.split()到另一個迭代第一:

entity = {key: value for p in props for key, value in (p.split('='),)} 

所以現在不是:

['key', 'value'] 

你得到:

(['key', 'value'],) 

其迭代只是一次,提供兩個解包值。

但是,您可以使用可在此處調用的dict();它消耗的(key, value)雙直接可迭代:

entity = dict(p.split('=') for p in props) 

你也應該儘量避免讀取整個文件到內存中,你可以使用文件作爲迭代直接

from itertools import takewhile 

parsed_entities = [] 
with open('foo.txt') as f: 
    cleaned = (l.rstrip('\n') for l in f) 
    while True: 
     props = takewhile(lambda n: n != 'EOM', cleaned) 
     parsed_entities.append(dict(p.split('=') for p in props)) 
     try: 
      next(cleaned) # consume line after EOM 
     except StopIteration: 
      # no more lines 
      break 
+0

你的解決方案絕對像魔術一樣工作,謝謝!但我想嘗試和理解。打印'p.split('=')'會產生'['a','b']'。爲什麼你說這是一個可變長度的序列? – Infinity

+1

@Infinity:''a''是一個長度爲1的字符串,但是你可以有''''或''''或更長或更短的字符串。 'for'循環遍歷這兩個字符串,而不是對它們,因此對於'['a','b']'你首先嚐試'key',value ='a''。這是行不通的,因爲一串長度只有一個字符。但'key,value ='ac''會起作用,這是一串長度爲2的字符串。 –

+0

終於明白了。謝謝 :) – Infinity