2015-01-28 2 views
1

Есть ли лучший способ в python генерировать словари списка, содержащие значения из списков, чем использование вложенных циклов for?Лучший способ выполнения вложенных циклов для генерации dict?

Пример:

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', ... ,'z'] 
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
chars = ["!", "@", "#", "$"] 

objects = [] 
for letter in alphabet: 
    for number in numbers: 
     for char in characters: 
      objects.append({ 
       'letter': letter, 
       'number': number, 
       'char': char 
      }) 

print objects 
# [{letter: 'a', 'number': 0, 'char':'!'}, {letter: 'a', 'number': 0, 'char':'@'}, ... 

Я пытаюсь выяснить, как сделать список dicts, который содержит все возможные комбинации из трех списков. Используя вложенные петли for в приведенном выше примере, это 26 x 10 x 4 петель. Я посмотрел на использование zip, но только сливает списки и не дает каждой уникальной комбинации.

Есть ли питонический способ сделать это быстрее, чем 26 x 10 x 4 петель?

Есть ли способ сделать это лениво через генератор? Если да, то как?

ответ

2

Для получения генератора запрошенную:

from itertools import product 

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', ... ,'z'] 
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
chars = ["!", "@", "#", "$"] 

combinations = product(alphabet, numbers, chars) 
generator = ({'letter': l, 'number': n, 'char': c} for l, n, c in combinations) 

Поскольку это генератор, он будет оценен o при необходимости:

list(generator) 
3

достаточно странно это itertools.product

import itertools 
alphabet = ['a', 'b', 'c', 'd', 'e', 'f','z'] 
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
chars = ["!", "@", "#", "$"] 
my_iter = itertools.product(alphabet,numbers,chars) 
my_keys = "letter number char".split() 
for data in my_iter: 
    print dict(zip(my_keys,data)) 
3

Вы можете использовать itertools.product вычислить декартово произведение между всеми предусмотренными итерируемыми:

import itertools 
import string 

for letter, number, char in itertools.product(string.ascii_lowercase, string.digits, string.punctuation): 
    print({'letter': letter, 'number': number, 'char': char}) 
+0

отличные мысли думают одинаково: P –

+0

Ха, хороший! :) –

Смежные вопросы