Pythonic способ превратить список строк в словарь с нечетно-индексированными строками в качестве ключей и четно-индексированными в качестве значений? - PullRequest
8 голосов
/ 21 июля 2010

У меня есть список строк, проанализированных откуда-то, в следующем формате:

[key1, value1, key2, value2, key3, value3, ...]

Я бы хотел создать словарь на основе этого списка, например:

{key1:value1, key2:value2, key3:value3, ...}

Обычный цикл for со смещением индекса, вероятно, сработает, но мне интересно, есть ли Pythonic способ сделать это. Понимание списка кажется интересным, но я не могу понять, как применить их к этой конкретной проблеме.

Есть идеи?

Ответы [ 5 ]

13 голосов
/ 21 июля 2010

Вы можете попробовать:

dict(zip(l[::2], l[1::2]))

Объяснение: мы разбили список на два списка, один из четных и один из нечетных элементов, выполнив их по шагам два, начиная с первого или второго элемента (это l[::2] и l[1::2] ). Затем мы используем zip, встроенный в два списка в один список пар. Наконец, мы вызываем dict для создания словаря из этих пар ключ-значение.

Это ~4n во времени и ~4n в пространстве, включая последний словарь. Однако он, вероятно, быстрее, чем цикл, поскольку операторы zip, dict и срезы написаны на C.

5 голосов
/ 22 июля 2010

Хорошая возможность отобразить мою любимую идиому Python:

>>> S = [1,2,3,4,5,6]
>>> dict(zip(*[iter(S)]*2))
{1: 2, 3: 4, 5: 6}

Эта хитрая строка передает два аргумента в zip(), где каждый аргумент является одинаковым итератором над S. zip() создает кортежи из 2 элементов, каждый раз вытягивая из итератора через zip. dict() затем преобразует эти кортежи в словарь.

Для экстраполяции:

S = [1,2,3,4,5,6]

I = iter(S)
dict(zip(I,I))
3 голосов
/ 21 июля 2010
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'}
1 голос
/ 22 июля 2010

В дополнение к короткому и совершенно прекрасному решению pavpanchekha, вы можете использовать выражение генератора (списочное понимание - это просто выражение генератора, переданное конструктору списка - на самом деле оно более мощное и универсальное) для дополнительной пользы:

dict((l[i], l[l+1]) for i in range(0, len(l)-1, 2))

Помимо того, что он действительно крутой и функциональный, он также является лучшим алгоритмом: если реализация dict не является особенно глупой (вряд ли она считается встроенной), она будет потреблять одинаковое количество памяти для каждого размера l (то есть работает в константе, известной как O (1), поскольку обрабатывает одну пару за раз, вместо того чтобы сначала создавать новый список кортежей.

0 голосов
/ 21 июля 2010
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 принимает список (key,value) соединяет и делает из них дикт.

Вы также можете написать result = dict(zip(*[iter(L)]*2)) и сбить с толку большинство читателей: -)

...