0

文字列の値に基づいて変数名を作成することは可能ですか?

情報ブロックのファイルを読み取り、それらを辞書に保存するスクリプトがあります。各ブロックの辞書は、「マスター」辞書に追加されます。ファイル内の情報のブロック数はさまざまで、「完了」という言葉を使用してブロックの終わりを示します。

私はこのようなことをしたい:

master={}
block=0
for lines in file:
  if line != "done":
    $block.append(line)
  elif line == "done":
    master['$block'].append($block)
    block = block + 1

ファイルに次のようなコンテンツがある場合:

eggs
done
bacon
done
ham
cheese
done

結果は、3 つのリストを持つ辞書になります。

master = {'0': ["eggs"], '1': ["bacon"], '2': ["ham", "cheese"]}

これはどのように達成できますか?

4

5 に答える 5

3

実際には、代わりにリストを使用することをお勧めします。配列っぽいdictが必要な理由はありますか?

配列を使用できる場合は、次を使用できます。

with open("yourFile") as fd:
    arr = [x.strip().split() for x in fd.read().split("done")][:-1]

出力:

[['eggs'], ['bacon'], ['ham', 'cheese']]

数値文字列インデックスが必要な場合は、次を使用できます。

with open("yourFile") as fd:
    l = [x.strip().split() for x in fd.read().split("done")][:-1]
    print dict(zip(map(str,range(len(l))),l))
于 2012-06-20T18:57:40.937 に答える
2

あなたは辞書がどのように機能するかを誤解しているようです。それらはオブジェクトであるキーを受け取るので、ここでは魔法は必要ありません。

collections.defaultdictただし、必要に応じてサブリストを作成するためにを使用することで、コードをより適切にすることができます。

from collections import defaultdict

master = defaultdict(list)
block = 0
for line in file:
    if line == "done":
        block += 1
    else:
        master[block].append(line)

ただし、連続した番号付きのインデックスが必要な場合は、辞書は不要であることをお勧めします。これがリストの目的です。その場合は、Thrustmasterの最初の提案に従うか、代わりに次のことをお勧めします。

from itertools import takewhile

def repeat_while(predicate, action):
    while True:
        current = action()
        if not predicate(current):
            break
        else:
            yield current

with open("test") as file:
    action = lambda: list(takewhile(lambda line: not line == "done", (line.strip() for line in file)))
    print(list(repeat_while(lambda x: x, action)))
于 2012-06-20T18:57:09.943 に答える
1

「完了」の分割は失敗する運命にあると思います。リストを検討してください:

eggs
done
bacon
done
rare steak
well done stake
done

Thrustmaster からの盗み (盗みに対して +1 を与えました) 私は提案します:

>>> dict(enumerate(l.split() for l in open(file).read().split('\ndone\n') if l))
{0: ['eggs'], 1: ['bacon'], 2: ['ham', 'cheese']}

これは末尾に「\n」が必要であることを知っています。質問がある場合は、"open(file).read()+'\n'" または "+'\n\ndone\n'" を使用できます (最終的な完了がオプションの場合)。

于 2012-06-20T19:55:50.627 に答える
0

setattrまたはglobals()を使用します。現在のモジュールでsetattr()を呼び出すにはどうすればよいですか?を
参照してください。

于 2012-06-20T18:56:55.543 に答える
0

並置のために、コードをもう一度示します。

master={}
block=0
for lines in file:
  if line != "done":
    $block.append(line)
  elif line == "done":
    master['$block'].append($block)
    block = block + 1

Thrustmaster の投稿で述べたように、ここではネストされたリストを使用する方が理にかなっています。これを行う方法は次のとおりです。元のコードから構造的にできるだけ変更していません。

master=[[]] # Start with a list containing only a single list
for line in file: # Note the typo in your code: you wrote "for lines in file"
  if line != "done":
    master[-1].append(line) # Index -1 is the last element of your list
  else: # Since it's not not "done", it must in fact be "done"
    master.append([])

ここでの唯一のことは、リストの最後に余分なリストが 1 つあるということです。そのため、最後の空のサブリストを取得masterする行を追加する必要があります。del

del master[-1]
于 2012-06-20T19:30:22.767 に答える