2009-12-22 2 views
6

У меня есть список, который выглядит примерно такКак получить значение по определенному индексу в списке python?

List = [q1,a1,q2,a2,q3,a3] 

мне нужен окончательный код, чтобы быть что-то вроде этого

dictionary = {q1:a1,q2:a2,q3:a3} 

если только я могу получить значения в определенный индекс, например, список [0] Я могу это сделать, есть ли способ получить его?

ответ

11

Словари Python могут быть построены с использованием класса dict с учетом итерации, содержащей кортежи. Мы можем использовать это в сочетании с встроенным range, чтобы создать набор кортежей, как в (каждый элемент-нечетный элемент, каждый-элемент), и передать его в dict, чтобы значения группировались в пары ключ/значение в конечный результат:

dictionary = dict([(List[i], List[i+1]) for i in range(0, len(List), 2)]) 
+2

Вы можете вынуть '[]' S, чтобы изменить список понимание к генератору для большей эффективности: 'ДИКТ ((List [я], список [я + 1]) для г в диапазоне (0 , len (List), 2)) 'Таким образом, он не будет генерировать список, чтобы позже выбросить его после преобразования в dict. –

+0

Ты, мой друг, спасатель жизни, да благословит тебя Бог. Я был на этом в течение двух часов –

+0

ОК, теперь я [] оставил вначале для совместимости с py2.3, * и * также тот факт, что я слышал точную противоположность - для очень маленьких коллекций построение списка быстрее, чем накладные расходы на создание генератора. Я могу попросить моего коллегу получить более подробную информацию об этом, но это имеет смысл. – zzzeek

11

Использование расширенного обозначения среза:

dictionary = dict(zip(List[0::2], List[1::2])) 
3

ответ диапазона на основе проще, но, возможно, другой подход с использованием пакета itertools:

from itertools import izip 
dictionary = dict(izip(*[iter(List)] * 2)) 

Ломая это вниз (редактирования: испытания на этот раз):

# Create instance of iterator wrapped around List 
# which will consume items one at a time when called. 
iter(List) 

# Put reference to iterator into list and duplicate it so 
# there are two references to the *same* iterator. 
[iter(List)] * 2 

# Pass each item in the list as a separate argument to the 
# izip() function. This uses the special * syntax that takes 
# a sequence and spreads it across a number of positional arguments. 
izip(* [iter(List)] * 2) 

# Use regular dict() constructor, same as in the answer by zzzeeek 
dict(izip(* [iter(List)] * 2)) 

Edit: во многом благодаря Chris Lutz»острые глаза для двойной коррекции.

+0

Типо в двух последних строках: нет конца ']' –

+0

Исправлена ​​опечатка, отмеченная Крисом (спасибо!) –

+0

Теперь вы положили ее неправильное место. 'iter (List) * 2' недействителен. –

0

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

from itertools import izip 

dictionary = {} 
for k, v in izip(List[::2], List[1::2]): 
    if k not in dictionary: 
     dictionary[k] = set() 
    dictionary[k].add(v) 

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

from itertools import izip 
from collections import defaultdict 

dictionary = defaultdict(set) 
for k, v in izip(List[::2], List[1::2]): 
    dictionary[k].add(v) 

Мы закончим со словарем, где все ключи являются наборами, а наборы содержат значения. Это может оказаться неприемлемым, потому что наборы, например словари, не могут содержать дубликаты, поэтому, если вам нужен один ключ для хранения двух одинаковых значений, вам нужно будет изменить его на кортеж или список. Но это должно заставить вас начать.

2
d = {} 
for i in range(0, len(List), 2): 
    d[List[i]] = List[i+1] 
+0

Thats точно, что я думал, самое простое и лучшее. :) –

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