2017-07-01 16 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は未定義です。

+0

私は思います'p.split( '=')'の長さは2ではありません。 –

+0

@SamChats:確かです。しかし 'p.split( '=')[0]'はそうではなく、解凍されているものです。 –

+0

@SamChats、それをチェックしました。私は 'p.split( '=')'を 'print(len(p.split( '=')))'に置き換え、それは2です。 – Infinity

答えて

6

あなたはこれを行うことはできません。それはまさにの要素を持っているp.split()コールのすべての結果を必要とするため

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

を。代わりに、可変長の単一(文字列)要素のシーケンスがあります。

あなたが別の反復可能な最初にp.split()をラップする必要があると思います:

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

だから今の代わり:

['key', 'value'] 

あなたが得る:

一度だけ を反復し
(['key', 'value'],) 

、解凍する2つの値を指定します。

ただし、ここでは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の文字列ですが、' 'foo''や' 'bar''やもっと長い文字列や短い文字列を使うことができます。 'for 'ループはそれらの2つの文字列を反復しますが、' [' a '、' b '] 'は最初に' key、value =' a''を実行しようとします。長さ1の文字列には1文字しか含まれていないため、これは機能しません。しかし、 'key、value = 'ac''は長さ2の文字列です。 –

+0

最後にそれを得ました。ありがとう:) – Infinity

関連する問題