2013-06-23 5 views
3

Есть ли более быстрый или более «питонический» способ доступа к значениям, связанным с одним ключом, в списке словарей, отличных от его циклирования (как показано на рисунке here)? Я ищу что-то вроде listDict[:]['id'], чтобы получить список valules, но я получаю ошибку list indices must be integers, not str, хотя listDict[0]['id'] работает просто отлично.ломтики в списке словарей

Обновление - вопрос последующего действия: Что делать, если значение для ключа также является самим списком, и меня интересуют только первые 10 его элементов?

При использовании понимания списка легко сделать [dic['id'][:10] for dic in listDict], но как насчет использования itemgetter? map(itemgetter('id')[:10], listDict), похоже, не работает.

Я спрашиваю о быстром способе получить доступ, потому что у меня есть огромный список словарей, и я думал, что могу получить то же поведение, что и массивы numpy (например, срезы представляют собой только виды исходного массива) для списков словари. Мне интересно, есть ли у python какой-либо способ использования факта, что все словари в моем списке имеют одинаковый размер для быстрого доступа к памяти с чередованием и копирования больших блоков данных за один раз, не делая промежуточных представлений в виде списка списков.

Спасибо!

+0

Извините, но это дубликат связанного вопроса вы дали, все такие же ответы – jamylak

+0

Я знал ответы на этот вопрос, и я если есть какие-то другие альтернативы. – bbudescu

+0

Самое питонное и самое быстрое решение - это принятый ответ – jamylak

ответ

4

Нет, вы не можете так нарезать здесь. Вы просматриваете весь список и выбираете элементы из каждого dict.

Используйте список понимание:

[dic['id'] for dic in listDict] 

или operator.itemgetter:

>>> from operator import itemgetter 
>>> map(itemgetter('id'), listDict) 

Зубчатые сравнений:

>>> listDict = [{'id':1,'other':2},{'id':3,'other':4},{'id':5,'other':6}] *100 

>>> %timeit [dic['id'] for dic in listDict] 
10000 loops, best of 3: 50.8 us per loop 
>>> %timeit map(itemgetter('id'), listDict) 
10000 loops, best of 3: 42.7 us per loop 

>>> listDict = [{'id':1,'other':2},{'id':3,'other':4},{'id':5,'other':6}]*1000 

>>> %timeit [dic['id'] for dic in listDict] 
1000 loops, best of 3: 446 us per loop 
>>> %timeit map(itemgetter('id'), listDict) 
1000 loops, best of 3: 440 us per loop 

>>> listDict = [{'id':1,'other':2},{'id':3,'other':4},{'id':5,'other':6}] *10**5 

>>> %timeit [dic['id'] for dic in listDict] 
10 loops, best of 3: 50.7 ms per loop 
>>> %timeit map(itemgetter('id'), listDict) 
10 loops, best of 3: 45.6 ms per loop 
+0

'map'' itemgetter' медленнее и уродливее, чем ваше первое заданное решение – jamylak

+0

@jamylak Это оказалось быстрее. –

+0

Не в крошечных списках, и разница незначительна – jamylak