Frage

Stellen Sie sich vor Ich habe diese Python-Listen:

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

Sie haben eine direkte oder zumindest eine einfache Möglichkeit, die folgende Liste der Wörterbücher zu produzieren?

[
    {'name': 'Monty', 'age': 42},
    {'name': 'Matt',  'age': 28},
    {'name': 'Frank', 'age': 33}
]
War es hilfreich?

Lösung

Hier ist die Reißverschluss Art und Weise

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

Andere Tipps

Es ist nicht schön, aber hier ist ein Einzeiler mit einer Liste Verständnis, zip und Schritt:

[dict(zip(keys, a)) for a in zip(values[::2], values[1::2])]

Dumb Weg, aber eine, die sofort zu meinem Sinne kommt:

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 fast tut, was Sie wollen; leider nicht die kürzere Liste Radfahren, er bricht. Vielleicht gibt es eine ähnliche Funktion, die Zyklen?

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

/ EDIT: Oh, wollen Sie eine Liste von dict . Die folgenden Werke (Dank an Peter, als auch):

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

In der Antwort von Konrad Rudolph

  

zip fast tut, was Sie wollen; leider nicht die kürzere Liste Radfahren, er bricht. Vielleicht gibt es eine ähnliche Funktion, die Zyklen?

Hier ist eine Art und Weise:

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

Ich werde es nicht nennen Pythonic (ich glaube, es ist zu klug), aber es könnte sein, was suchen.

Es gibt keinen Nutzen in Aus- und Einschalten der keys Liste mit itertools .cycle(), weil jeder Traversal von keys entspricht die Schaffung einer Dictionnary.

EDIT: Hier ist eine andere Art und Weise:

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

Das ist viel pythonic: Es gibt eine lesbare Nutzenfunktion mit einem klaren Zweck, und der Rest des Codes fließt natürlich aus ihr

.

Hier ist mein einfacher Ansatz. Es scheint die Idee nahe zu sein, dass @Cheery außer hatte, dass ich die Eingabeliste zerstören.

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

Noch ein anderer versuchen, vielleicht dümmer als die erste:

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'}]

Aber es ist an Ihnen zu entscheiden, ob es dümmer.

[dict(zip(keys,values[n:n+len(keys)])) for n in xrange(0,len(values),len(keys)) ]

UG-LEEE. Ich würde es hassen, den Code zu sehen, die so aussieht. Aber es sieht recht.

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 )

Noch ein wenig hässlich, aber die Namen helfen einen Sinn geben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top