У меня есть список строк, проанализированных от где-нибудь в следующем формате:
[key1, value1, key2, value2, key3, value3, ...]
Я хотел бы создать словарь на основе этого списка, как так:
{key1:value1, key2:value2, key3:value3, ...}
Дежурное блюдо for
цикл с индексными смещениями, вероятно, добился бы цели, но интересно, существует ли Pythonic способ сделать это. Понимания списка кажутся интересными, но я, может казаться, не узнаю, как применить их к этой конкретной проблеме.
Какие-либо идеи?
Вы можете попробовать:
dict(zip(l[::2], l[1::2]))
Объяснение: мы разбиваем список на два списка, один из четных и один из нечетных элементов, разбивая их на два шага, начиная с первого или второго элемента (т.е. l [:: 2]
и l [1 :: 2]
). Затем мы используем встроенную функцию zip
, чтобы объединить два списка в один список пар. Наконец, мы вызываем dict
, чтобы создать словарь из этих пар ключ-значение.
Это ~ 4n
во времени и ~ 4n
в пространстве, включая окончательный словарь. Однако это, вероятно, быстрее, чем цикл, поскольку операторы zip
, dict
и срезы написаны на C.
Хорошая возможность показать мою любимую идиому о питоне:
>>> S = [1,2,3,4,5,6]
>>> dict(zip(*[iter(S)]*2))
{1: 2, 3: 4, 5: 6}
Эта хитрая строка передает два аргумента в zip ()
, где каждый аргумент тот же ] итератор над S. zip ()
создает кортежи из двух элементов, каждый раз извлекая их из итератора через zip. dict ()
затем преобразует эти кортежи в словарь.
Для экстраполяции:
S = [1,2,3,4,5,6]
I = iter(S)
dict(zip(I,I))
In [71]: alist=['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
In [72]: dict(alist[i:i+2] for i in range(0,len(alist),2))
Out[72]: {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
В дополнение к короткому и прекрасному решению pavpanchekha вы можете использовать выражение генератора (понимание списка - это просто выражение генератора, передаваемое в конструктор списка - на самом деле оно более мощное и универсальное) для дополнительных доброта:
dict((l[i], l[l+1]) for i in range(0, len(l)-1, 2))
Помимо того, что это действительно круто и функционально, это еще и лучший алгоритм: если реализация dict не является особенно глупой (маловероятно, что она является встроенной), она будет потреблять один и тот же объем памяти для каждого размера l (т.е. выполняется в постоянном пространстве, известном как O (1)), поскольку он обрабатывает одну пару за раз вместо того, чтобы сначала создавать целый новый список кортежей.
result = dict(grouper(2, L))
grouper
- это функция, которая формирует пары в списке, она указана в рецептах itertools :
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
dict
принимает список (ключ, значение)
объединяет и делает из них диктант.
Вы также можете написать result = dict (zip (* [iter (L)] * 2))
и запутать большинство читателей: -)