0

たとえば、テキストファイルがあります。

RootObject: Sun

Object: Sun
Satellites: Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris
Radius: 20890260
Orbital Radius: 0

Object: Earth
Orbital Radius: 77098290
Period: 365.256363004
Radius: 6371000.0
Satellites: Moon

Object: Moon
Orbital Radius: 18128500
Radius: 1737000.10
Period: 27.321582

そして私はそれを辞書に入力しようとしています。これは私がこれまでに持っているものですが、私はエラーを受け取り続けます...

#d = dictionary
#new_d = new dictionary

file = open("data.txt","r")
d = {}
def data(file):
    for line in file:
        if line != line.strip:
            continue
        line = line.strip()
        key = line.split(":")
        val = line.split(":")
        if key in d and key == "Object":
            print(d)
        d[key] = val
    print(d)

new_d = {}
with file as x:
    for d in data(x):
        new_d[d["Object"]] = d
print(nd)

私は次のようなものを取得する必要があります:

{' Earth': {'Satellites': ' Moon', 'Orbital Radius': ' 77098290', 'Object': ' Earth', 'Radius': ' 6371000.0', 'Period': ' 365.256363004'}, ' Moon': {'Orbital Radius': ' 18128500', 'Object': ' Moon', 'Radius': ' 1737000.10', 'Period': ' 27.321582'}, ' Sun': {'Satellites': ' Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris', 'Orbital Radius': ' 0', 'Object': ' Sun', 'Radius': ' 20890260', 'RootObject': ' Sun'}}

このエラーが発生します:

Traceback (most recent call last):
  File "planet2.py", line 21, in <module>
    for d in data(x):
TypeError: 'NoneType' object is not iterable
4

2 に答える 2

2

これはうまくいくでしょう:

file = open("data.txt","r")

def data(file):
    dic = {}
    for line in file:
        # If line not blank
        if line.strip() != '':
            key,value = line.split(":")
            if key == 'RootObject':
                dic[key] = value.strip()
            elif key == 'Object':
                # Get the Object value i.e Earth, Moon, Sun                
                obj = value.strip()
                # Create entry with obj key and blank dictionary value
                dic[obj]={}
            else:
                # Populate the blank dictionary with key, value pairs
                dic[obj][key] = value.strip()
    return dic

planets = data(file)

# Usage
print planets
print planets['Earth']
print planets['Earth']['Radius']

出力:

# The whole dictionary 
{'Sun': {'Satellites': 'Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris', 'Orbital Radius': '0', 'Radius': '20890260'}, 'Moon': {'Orbital Radius': '18128500', 'Radius': '1737000.10', 'Period': '27.321582'}, 'Earth': {'Satellites': 'Moon', 'Orbital Radius': '77098290', 'Radius': '6371000.0', 'Period': '365.256363004'}}

# The Earth dictionary
{'Satellites': 'Moon', 'Orbital Radius': '77098290', 'Radius': '6371000.0', 'Period': '365.256363004'}

# The Earth's radius
6371000.0
于 2012-11-22T20:57:59.500 に答える
1

コードにはいくつかの異なるエラーがあります。例外の原因となっているのは、関数dataがグローバル変数に書き込み、何も返さないことですが、後のコードでは、シーケンスやジェネレーターなどの反復可能なものが返されることを期待しています。

これを修正するには、トップレベルのコードをグローバルディクショナリで直接反復するか、グローバルを削除してその中にディクショナリを作成dataし、最後に返すことができます。コードがより複雑になるにつれてグローバル変数を処理するのは難しいので、後者をお勧めします。

これがどのように機能するかについての大まかな概要です(後で説明するので、真ん中の部分は大ざっぱなままにしておきます):

def data(file):
    objects = {}

    # add stuff to objects dict

    return objects

次のエラーは、行を削除することです。strip現在、コードは独自のメソッドを使用して各行の不等式をテストしています。これはPython3のエラーです。これは、lineline.stripが比較できないタイプであるためです。しかし、それがうまくいったとしても、それは無意味でしょう。空の行を最初に削除し、後で空の行を拒否することで、空の行を削除しようとしていたのではないかと思います。これを行う方法は次のとおりです。

if not line.strip():
    continue

これは、Pythonコミュニティの一部の人々が「飛躍する前に見る」(LBYL)プログラミングスタイルと呼んでいるものの例です。問題になる前に問題になる可能性のあるものをチェックしているからです。try別の方法は、問題が発生する可能性のある領域をブロックでラップし、生成された例外をキャッチする「許可よりも許しを求めるのが簡単」(EAFP)スタイルです。EAFPスタイルは、より「Pythonic」と見なされることがあるため、そのスタイルについては後で説明します。

次のエラーは論理的なものであり、エラーを引き起こすものではありません。key行を分割していて、その2つの部分を変数とに分割したいとしますvalue。ただし、これらの変数に対して2つの別々の割り当てを行っているため、実際には、それぞれで同じ値になります。これは、Python構文の優れた機能を使用して解凍する場所です。各変数を個別に割り当てる代わりに、2つの値のシーケンス(リストやタプルなど)を両方に一緒に割り当てることができます。Pythonは、最初の値を最初の変数に、2番目の値を2番目の変数に与える処理を行います。外観は次のとおりです。

key, value = line.split(":")

もちろん、行にコロンがない場合、これは失敗しtryます。したがって、EAFPスタイルのコーディングを使用している場合は、ブロックを配置するのに適した場所です。これを行う1つの方法は次のとおりです。

try:
    key, value = line.split(":")
except ValueError:
    continue

代わりにtry、ループ内に残っているすべてのものの周りにブロックを配置し、exceptブロックにのみを含めることができますpass(これは何もしませんが、例外を無視します)。

最後に、ネストされた辞書の作成方法に関係する最後の論理エラーがあります。現在のアプローチは、最初にファイルのすべてのキーと値を使用して単一の辞書を作成し、次にそれらを天体ごとに1つずつ別々の部分に分割することです。ただし、各オブジェクトのキーが同じである場合、これは機能しません。たとえば、各オブジェクトには「軌道半径」キーがあるため、それらはすべて互いに上書きし、そのキーを1つの辞書に入れます。

@sudo_oの答えは、内部辞書を作成して値を入力する方法を示しています(これは私が作成しようとしていたものとほぼ同じです)。残りの説明を投稿したかっただけです。

于 2012-11-22T21:06:22.470 に答える