2

Python では、明示的な型チェックを使用して解決したリストと辞書を変換して、整数と整数のリストの違いを判断するという単純な問題があります。私はPythonに少し慣れていません。問題を解決するためのより「pythonic」な方法、つまり明示的な型チェックを回避する方法があるかどうか知りたいです。

要するに、値を使用して辞書のキーをソートしようとしていますが、各キーには複数の値を含めることができ、キーはリストに複数回表示する必要があります。データは の形式で提供され{'a':1, 'b':[0,2],...}ます。私が ( sorted( , key = ) を使用して) 思いついたことはすべて、リスト 1 の長さではなく、整数としてではなく、一度発生する値を指定できるという事実によってつまずきます。

{'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}フォームの辞書とリストの間で変換したいと思います['b', 'd', 'c', 'a', 'c', 'd'](リスト内の項目の位置は、辞書の値によって指定されます)。

この関数list_to_dictionaryには、リストに表示される各項目のキーと、リスト内の場所を示す値が必要です。アイテムが複数回表示される場合、値はそれらのすべての場所を格納するリストにする必要があります。

この関数dictionary_to_listは、値でソートされたディクショナリのキーで構成されるリストを作成する必要があります。値が単一の整数ではなく、整数のリストである場合、そのキーは、対応するソートされた場所でリストに複数回表示される必要があります。

私の解決策は次のとおりです。

def dictionary_to_list(d):
"""inputs a dictionary a:i or a:[i,j], outputs a list of a sorted by i"""    
    #Converts i to [i] as value of dictionary
    for a in d:
        if type(d[a])!=type([0,1]):
            d[a] = [d[a]]

    #Reverses the dictionary from {a:[i,j]...} to {i:a, j:a,...}
    reversed_d ={i:a for a in d for i in d[a]}

    return  [x[1] for x in sorted(reversed_d.items(), key=lambda x:x[0])]

def list_to_dictionary(x):
    d = {}        
    for i in range(len(x)):
        a = x[i]            
        if a in d:
            d[a].append(i)
        else:
            d[a]=[i]
    #Creates {a:[i], b:[j,k],...}

    for a in d:
        if len(d[a])==1:
            d[a] = d[a][0]
    #Converts to {a:i, b:[j,k],...}

    return d

コードの残りの部分との相互作用のために、辞書の値として単一の整数の代わりに長さ 1 のリストを持つように問題を変更することはできません。これを処理する簡単な方法があるはずですが、わかりません。ここでのより良い解決策は、私の python スクリプトにいくつかのアプリケーションを用意することです。

ありがとう

4

3 に答える 3

1
def dictionary_to_list(data):
    result = {}
    for key, value in data.items():
        if isinstance(value, list):
            for index in value:
                result[index] = key
        else:
            result[value] = key
    return [result[key] for key in sorted(result)]

def list_to_dictionary(data):
    result = {}
    for index, char in enumerate(data):
        result.setdefault(char, [])
        result[char].append(index)
    return dict((key, value[0]) if len(value) == 1 else (key, value) for key, value in result.items())

dictData = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}
listData = ['b', 'd', 'c', 'a', 'c', 'd']

print dictionary_to_list(dictData)
print list_to_dictionary(listData)

出力

['b', 'd', 'c', 'a', 'c', 'd']
{'a': 3, 'c': [2, 4], 'b': 0, 'd': [1, 5]}
于 2013-10-30T06:23:02.280 に答える
1
In [17]: d = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}

In [18]: sorted(list(itertools.chain.from_iterable([[k]*(1 if isinstance(d[k], int) else len(d[k])) for k in d])), key=lambda i:d[i] if isinstance(d[i], int) else d[i].pop(0))
Out[18]: ['b', 'd', 'c', 'a', 'c', 'd']

電話は次のとおりです。

sorted(
  list(
    itertools.chain.from_iterable(
      [[k]*(1 if isinstance(d[k], int) else len(d[k])) 
        for k in d
      ]
    )
  ), 
  key=lambda i:d[i] if isinstance(d[i], int) else d[i].pop(0)
)

アイデアは、最初の部分 (つまりlist(itertools.chain.from_iterable([[k]*(1 if isinstance(d[k], int) else len(d[k])) for k in d]))、 にキーのリストを作成し、dそれに関連付けられた値の数だけ繰り返すことです。したがって、キーがその値として単一int(または 1 つだけを含むリストint) を持つ場合、それは に 1 回出現します。それ以外の場合は、リスト内のアイテムの数だけ表示されます。

次に、値がソートされていると仮定します (それ以外の場合、前処理ステップとして実行するのは簡単です)。ここで、キーを最初の値でソートします。値として int が 1 つしかない場合は、それが考慮されます。それ以外の場合は、すべての値を含むリストの最初の要素。この最初の要素も (pop の呼び出しによって) リストから削除されるため、同じキーが次に出現しても同じ値が再利用されません。

明示的な型チェックなしでこれを行いたい場合は、前処理ステップとしてすべての値をリストできます。

In [22]: d = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}

In [23]: d = {k:v if isinstance(v, list) else [v] for k,v in d.iteritems()}

In [24]: d
Out[24]: {'a': [3], 'b': [0], 'c': [2, 4], 'd': [1, 5]}

In [25]: sorted(list(itertools.chain.from_iterable([[k]*len(d[k]) for k in d])), key=lambda i:d[i].pop(0))
Out[25]: ['b', 'd', 'c', 'a', 'c', 'd']
于 2013-10-30T06:26:44.750 に答える
0
def dictionary_to_list(d):
    return [k[0] for k in sorted(list(((key,n) for key, value in d.items() if isinstance(value, list) for n in value))+\
    [(key, value) for key, value in d.items() if not isinstance(value, list)], key=lambda k:k[1])]

def list_to_dictionary(l):
    d = {}
    for i, c in enumerate(l):
        if c in d:
            if isinstance(d[c], list):
                d[c].append(i)
            else:
                d[c] = [d[c], i]
        else:
            d[c] = i
    return d
l = dictionary_to_list({'a':3, 'b':0, 'c':[2,4], 'd':[1,5]})
print(l)
print(list_to_dictionary(l))
于 2013-10-30T06:44:53.700 に答える