6

これらのpythonリストがあると想像してください:

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]

次の辞書のリストを作成する直接的または少なくとも簡単な方法はありますか?

[
    {'name': 'Monty', 'age': 42},
    {'name': 'Matt',  'age': 28},
    {'name': 'Frank', 'age': 33}
]
4

8 に答える 8

14

ジップウェイはこちら

def mapper(keys, values):
    n = len(keys)
    return [dict(zip(keys, values[i:i + n]))
            for i in range(0, len(values), n)]
于 2008-10-28T19:35:22.387 に答える
3

きれいではありませんが、リスト内包表記、zip、およびステッピングを使用したワンライナーを次に示します。

[dict(zip(keys, a)) for a in zip(values[::2], values[1::2])]
于 2008-10-28T20:09:51.130 に答える
2

ばかげた方法ですが、すぐに頭に浮かぶのは次のとおりです。

def fields_from_list(keys, values):
    iterator = iter(values)
    while True:
        yield dict((key, iterator.next()) for key in keys)

list(fields_from_list(keys, values)) # to produce a list.
于 2008-10-28T19:11:35.820 に答える
2

zipあなたが望むことをほとんど行います。残念ながら、短いリストを循環させるのではなく、壊れてしまいます。おそらく、循環する関連機能がありますか?

$ python
>>> keys = ['name', 'age']
>>> values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
>>> dict(zip(keys, values))
{'age': 42, 'name': 'Monty'}

/編集: ああ、 dictのリストが必要です。次の作品 (Peter にも感謝):

from itertoos import cycle

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]

x = zip(cycle(keys), values)
map(lambda a: dict(a), zip(x[::2], x[1::2]))
于 2008-10-28T19:13:29.543 に答える
2

コンラート・ルドルフによる回答

zip はほとんどあなたが望むことをします。残念ながら、短いリストを循環させるのではなく、壊れてしまいます。おそらく、循環する関連機能がありますか?

方法は次のとおりです。

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
iter_values = iter(values)
[dict(zip(keys, iter_values)) for _ in range(len(values) // len(keys))]

私はこれを Pythonic とは呼びません (あまりにも賢いと思います) が、探しているものかもしれません。

keysを使用してリストを循環させる利点はありません。これは、 の各走査が 1 つの辞書の作成に対応するためです。itertools.cycle()keys

編集:ここに別の方法があります:

def iter_cut(seq, size):
    for i in range(len(seq) / size):
        yield seq[i*size:(i+1)*size]

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
[dict(zip(keys, some_values)) for some_values in iter_cut(values, len(keys))]

これはより Pythonic です: 明確な目的を持つ読みやすいユーティリティ関数があり、残りのコードはそこから自然に流れます。

于 2008-10-28T19:55:04.093 に答える
1

これが私の簡単なアプローチです。入力リストを破棄することを除いて、@ Cheery が持っていたアイデアに近いようです。

def pack(keys, values):
  """This function destructively creates a list of dictionaries from the input lists."""
  retval = []
  while values:
    d = {}
    for x in keys:
      d[x] = values.pop(0)
    retval.append(d)
  return retval
于 2008-10-28T19:16:01.800 に答える
1

おそらく最初のものよりも愚かな、さらに別の試み:

def split_seq(seq, count):
    i = iter(seq)
    while True:
        yield [i.next() for _ in xrange(count)]

>>> [dict(zip(keys, rec)) for rec in split_seq(values, len(keys))]
[{'age': 42, 'name': 'Monty'},
 {'age': 28, 'name': 'Matt'},
 {'age': 33, 'name': 'Frank'}]

しかし、それが馬鹿げているかどうかを決めるのはあなた次第です。

于 2008-10-28T19:28:24.380 に答える
0
[dict(zip(keys,values[n:n+len(keys)])) for n in xrange(0,len(values),len(keys)) ]

UG-LEEE。私はそのようなコードを見たくありません。しかし、それは正しく見えます。

def dictizer(keys, values):
   steps = xrange(0,len(values),len(keys))
   bites = ( values[n:n+len(keys)] for n in steps)
   return ( dict(zip(keys,bite)) for bite in bites )

まだ少し醜いですが、名前はそれを理解するのに役立ちます.

于 2008-10-29T18:25:12.917 に答える