2

Цель: разработка аналог выраженияPython: ДИКТ понимание с несколькими парами ключ-значение в то же время

{k1: v1, k2: v2 for k1, k2, v1, v2 in data} 

или более частный случай {k1: v, k2: v for k1, k2, v, _ in data}

, что перебирает data только 1 раз (в приведенных примерах data - истребимый объект 4-х кортежей).

(И подобный вопрос о списке понимание, например [myfunc1(v1), myfunc2(v2) for v1, v2 in data]).

я могу предположить, единственное решение, используя собственный итератор:

def getby(iterable_data, iterable_indexes): 
    for indexed_data in iterable_data: 
     for tupl in iterable_indexes: 
      yield tuple(indexed_data[ind] for ind in tupl) 
    raise StopIteration 

Пример работы: list(getby([('a', 'b', 'c'), ('d', 'e', 'f', 'g')], [(0, 1), (2, 1)])) возвращается [('a', 'b'), ('c', 'b'), ('d', 'e'), ('f', 'e')]. Но возможно это медленно.

Я также могу предположить, эквивалентное выражение, например выше в терминах itertools.chain и itertools.groupby:

list(chain.from_iterable(lst for lst, _ in groupby([('a', 'b', 'c'), ('d', 'e', 'f', 'g')], 
                lambda lst: [(lst[0], lst[1]), (lst[2], lst[1])]))) 

Но возможно это некрасиво.

IPython на основе сравнения двух раствора: первые 1000 петель, лучше всего из 3: 20,2 мс за петли, вторые 1000 петли, лучший из 3: 4.12 мс на петле, поэтому второе решение действительно быстрее. Но может быть, более элегантное решение существует?

+2

Может '{к: V для k1 , k2, v1, v2 в данных для k, v in ((k1, v1), (k2, v2))}? Частный случай: '{k: v для k1, k2, v, _ в данных для k in (k1, k2)}'. – Delgan

+0

@ Delgan, конечно! Это действительно элегантное решение, которое работает немного быстрее! Благодаря! – kupgov

+0

Нет проблем, не забудьте принять решение @Martijn. ;) – Delgan

ответ

1

Формат понимания строго ограничен один результат за итерацию. Вы можете добавить дополнительные петли, хотя, к петле над множеством элементов, которые вы хотите вставить:

{k: v for k1, k2, v1, v2 in data for k, v in ((k1, v1), (k2, v2))} 

или ваш второй пример:

{k: v for k1, k2, v, _ in data for k in (k1, k2)} 

, который является эквивалентом:

result = {} 
for k1, k2, v1, v2 in data: 
    for k in (k1, k2): 
     result[k] = v 

Если вы можете написать что-то в виде вложенных циклов, возможно с if заявлениями между ними, только с один заявление на самом внутреннем уровень, который присваивает пару ключ-значение, тогда вы можете выразить его в понимании словаря.

Вы можете сделать это тоже с chain.from_iterable(), но затем производят списки или кортежи с последовательностью пар ключ-значение, и передать результат в dict() функции:

dict(chain.from_iterable(((k1, v1), (k2, v2)) for k1, v1, k2, v2 in data)) 
dict(chain.from_iterable(((k1, v), (k2, v)) for k1, k2, v, _ in data)) 

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

  • Нет связанных вопросов^_^