3

私はこのような口述を持っています:

(100002:'APPLE'、100004:'BANANA'、100005:'CARROT')

私は自分のdictにキーのintを持たせようとしていますが(現在のように)、値のセットを持っています(現在の文字列ではありません)。私の目標は、1つの列を持つ.csvファイルから読み取ることができるようにすることです。キー(アイテムID番号であるint)の場合、次にサイズ、形状、色などの列の場合。この情報をdictに追加して、すでにdictにあるキーの情報のみが追加されるようにします。

私の目標の口述は次のようになります。

(100002: set(['APPLE','MEDIUM','ROUND','RED']), 100004: set(['Banana','MEDIUM','LONG','YELLOW']), 100005: set(['CARROT','MEDIUM','LONG','ORANGE'])

アイテム名のキーと文字列だけの辞書から始めて、次のようなコードを試して、.csvファイルから追加情報を読み込みました。

infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
    spl_line = line.split(',')
    if int(spl_line[0]) in MyDict.keys():
        MyDict[int(spl_line[0])].update(spl_line[1:])

残念ながら、これはエラーになりますAttributeError: 'str' object has no attribute 'update'。辞書の値をセットに変更して、それらを更新できるようにしようとすると、次のような結果(100002: set(['A','P','L','E']), 100004: set(['B','A','N']), 100005: set(['C','A','R','O','T'])) になります。値をセットに変換して、現在値である文字列がセットの最初の文字列になるようにします。文字列を文字に分割してそれらの文字のセットを作成するよりも。

また、2つのリストを一緒に圧縮してdictを作成するときに値をセットにしようとしましたが、違いは見られませんでした。このMyDict=dict(zip(listofkeys、set(listofnames)))のようなものでも、listofnamesリスト全体がセットになりますが、MyDictの各値をlistofnamesの対応する文字列を含むセットにするという私の目標は達成されません。セットの最初の文字列。

MyDictの値をセットにして、現在dictの値である文字列を個々の文字のセットに変換せずに、そのセットに文字列を追加するにはどうすればよいですか?

編集:私は現在、1つの関数を使用してアイテムID(キー)のリストを生成し、別の関数を使用してそれらのアイテムIDを検索して対応するアイテム名のリストを生成することによってMyDictを作成しています(2列の.csvファイルをデータソース)そして私はzipそれらを一緒に。

答え:ここでの提案を使用して、私はこの解決策を思いつきました。set())。updateがあるセクションは、list())。appendに簡単に変更して、セットではなくリストを生成できることがわかりました(順序が保持されるように)。また、。で更新する方が簡単であることがわかりました。名前を含む列をFileWithTheData.csvに追加することにより、csvデータ入力ファイルを作成します。これにより、dictを作成し、値をセットに変換してから、さらにデータを追加する必要がなくなりました。このセクションのコードは次のようになります。

MyDict = {}
infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
    spl_line = line.split(',')
    if int(spl_line[0]) in itemidlist: #note that this is the list I was formerly zipping together with a corresponding list of names to make my dict
        MyDict.setdefault(int(spl_line[0]), list()).append(spl_line[1:])
print MyDict
4

2 に答える 2

4

エラーは、元々MyDict変数が整数を文字列にマップしているためです。あなたがそれを更新しようとしているとき、あなたはset,それが文字列であるときのように値を扱っています。

これにはdefaultdictを使用できます。

combined_dict = defaultdict(set)

# first add all the values from MyDict
for key, value in MyDict.iteritems():
    combined_dict[int(key)].add(value)

# then add the values from the file
infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
    spl_line = line.split(',')
    combined_dict[int(sp_line[0])].update(spl_line[1:])
于 2012-11-08T17:34:51.487 に答える
2

問題は、初期化の方法にMyDictあります。次のように変更してみてください。

MyDict = dict(zip(listofkeys, [set([name]) for name in listofnames]))

違いの簡単な例を次に示します。

>>> listofkeys = [100002, 100004, 100005]
>>> listofnames = ['APPLE', 'BANANA', 'CARROT']
>>> dict(zip(listofkeys, set(listofnames)))
{100002: 'CARROT', 100004: 'APPLE', 100005: 'BANANA'}
>>> dict(zip(listofkeys, [set([name]) for name in listofnames]))
{100002: set(['APPLE']), 100004: set(['BANANA']), 100005: set(['CARROT'])}

set(listofnames)リストをセットに変換するだけで、上記のように値を並べ替えるだけで効果があります。実際には、リスト内の各文字列値を取得し、それを1つの要素のセットに変換する必要があります。これは、リスト内包表記が行うことです。

この変更を行った後、現在のコードは正常に機能するはずですが、キーを明示的にチェックする代わりに、辞書で直接包含チェックを実行できます(key in MyDictと同じkey in MyDict.keys()です)。

于 2012-11-08T17:38:17.573 に答える