質問

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

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

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

[
    {'name': 'Monty', 'age': 42},
    {'name': 'Matt',  'age': 28},
    {'name': 'Frank', 'age': 33}
]
役に立ちましたか?

解決

こちらがzip方法です

def mapper(keys, values):
    n = len(keys)
    return [dict(zip(keys, values[i:i + n]))
            for i in range(0, len(values), n)]

他のヒント

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

[dict(zip(keys, a)) for a in zip(values[::2], values[1::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.

zip は、ほぼ必要なことを行います。残念ながら、短いリストを繰り返すのではなく、壊れます。おそらく、循環する関連関数がありますか?

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

/ EDIT:ああ、 dict リストが必要です。次の作品(ピーターにも感謝):

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]))

Konrad Rudolphによる回答

  

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 リストを循環してもメリットはありません。 = "nofollow noreferrer"> itertools .cycle()。これは、 keys の各走査が1つの辞書の作成に対応するためです。

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

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))]

これははるかにPython的です。明確な目的を持った読み取り可能なユーティリティ関数があり、残りのコードはそこから自然に流れます。

これが私の簡単なアプローチです。入力リストを破棄する以外は@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

まだ最初の試行よりも恐ろしいもう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'}]

しかし、それが愚かであるかどうかを決めるのはあなた次第です。

[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 )

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top