Squeak.ru - шаблоны программирования

Выбор объектов в словарях Python на основе значений

Я новичок в Python, решив сделать прыжок с Matlab. Я пытался найти ответ на свой вопрос несколько дней, но безуспешно!

Проблема: у меня есть несколько объектов с определенными атрибутами. Обратите внимание, что я не говорю об объектах и ​​атрибутах в программном смысле этого слова - я говорю о буквальных астрономических объектах, для которых у меня есть различные типы числовых данных и физических атрибутов.

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

for i in range ( len(ObjectCatalogue) )

    calculate quantity1 for source i    

    calculate quantity2 for source i 

    determine attribute1 for source i 

    sourceDataDict[i].update( {'spectrum':quantity1} )

    sourceDataDict[i].update( {'peakflux':quantity2} )

    sourceDataDict[i].update( {'morphology':attribute1} )

Итак, после того, как я просмотрел сотню источников или около того, я могу, скажем, получить доступ к спектру для объекта №. 20 с SpectrumSource20 = sourceData [20] ['спектр'] и т. Д.

Что я хочу сделать, так это иметь возможность выбирать все объекты в словаре на основе значения ключевого слова «морфология», скажем. Скажем, ключевое слово «морфология» может принимать значения «простой» или «сложный». Есть ли способ сделать это, не прибегая к петле? Т.е. - Могу ли я сделать что-нибудь вроде создания нового словаря, содержащего все источники, которые принимают «сложное» значение для ключевого слова «морфология»?

Трудно объяснить, но при использовании привычной мне логической индексации из Matlab это выглядело бы примерно так:

complexSourceDataDict = sourceDataDict[*]['morphology'=='complex']

(где * обозначает все объекты в словаре)

В любом случае - любая помощь будет принята с благодарностью!


  • Зависит от. Что такое sourceDataDict? Это действительно словарь или список, содержащий словари? 19.11.2012
  • Вы можете посмотреть библиотеку под названием pandas. Он предоставляет табличную структуру данных, которая обеспечивает доступ как вам угодно. 19.11.2012

Ответы:


1

Без шлейфа нет. При понимании списка да:

complex = [src for src in sourceDataDict.itervalues() if src.get('morphology') == 'complex']

Если sourceDataDict действительно является списком, вы можете отбросить itervalues:

complex = [src for src in sourceDataDict if src.get('morphology') == 'complex']

Если подумать, оценка * в любом случае будет означать операцию цикла под капотом (при условии, что это правильный синтаксис). Итак, ваш трюк состоит в том, чтобы сделать наиболее эффективный цикл, который вы можете использовать с используемой структурой данных.

Единственный способ стать более эффективным - это заранее проиндексировать все ключи «морфологии» объектов данных и поддерживать их в актуальном состоянии.

19.11.2012

2

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

Наиболее эффективным решением, вероятно, было бы создание дополнительного словаря, который индексировал бы любые характеристики, которые вас интересуют. Например, чтобы найти значения со значением 'morphology' 'complex', вы должны сделать что-то вроде этого:

from collections import defaultdict

# set up morphology dict (you could do this as part of generating the morphology)
morph_dict = defaultdict(list)
for data in sourceDataDict.values():
    morph_dict[data["morphology"]].append(data)

# later, you can access a list of the values with any particular morphology
complex_morph = morph_dict["complex"]

Хотя это высокая производительность, может раздражать необходимость заранее настраивать обратные индексы для всего. Альтернативой может быть использование понимания списка или выражения генератора для перебора словаря и поиска подходящих значений:

complex = (d for d in sourceDataDict.values() if d["morphology"] == "complex")

for c in complex:
    do_whatever(c)
19.11.2012

3

Я считаю, что вы имеете дело со структурой, подобной следующей

sourceDataDict = [
    {'spectrum':1,
    'peakflux':10,
     'morphology':'simple'
    },
    {'spectrum':2,
    'peakflux':11,
     'morphology':'comlex'
     },
    {'spectrum':3,
    'peakflux':12,
     'morphology':'simple'
     },
    {'spectrum':4,
    'peakflux':13,
     'morphology':'complex'
     }
    ]

вы можете сделать что-то подобное, используя List COmpferenceion

>>> [e for e in sourceDataDict if e.get('morphology',None) == 'complex']
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

Используя itertools.ifilter, вы можете добиться аналогичного результата

>>> list(itertools.ifilter(lambda e:e.get('morphology',None) == 'complex', sourceDataDict))
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

Обратите внимание, что использование get вместо индексации гарантирует, что функциональность не откажется, даже если ключевой «морфология» не существует. В случае, если его существование определенно, вы можете переписать приведенное выше как

>>> [e for e in sourceDataDict if e['morphology'] == 'complex']
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

>>> list(itertools.ifilter(lambda e:e['morphology'] == 'complex', sourceDataDict))
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]
19.11.2012
  • Я не хочу придираться, но зачем предлагать каждый раз добавлять дополнительные накладные расходы на вызов функции с помощью лямбда? Теперь он должен вызвать лямбду, которая вызывает get 19.11.2012
  • @jdi: использование get гарантирует, что получение ключа не завершится ошибкой, если ключ не существует. В случае, если очевидно, что ключ будет всегда, можно просто использовать индексирование по словарю. Я не большой поклонник лямбда, но людям, пришедшим из Matlab, действительно трудно понять LC. 19.11.2012
  • Я согласен. Вот почему я использовал get в своем собственном ответе. Но я говорю, что вы добавляли второй вызов функции каждый раз, когда она должна быть вызвана. Лямбда. Я тоже использую лямбды там, где это необходимо. Но это просто накладные расходы. Что касается get, вам не нужно использовать None arg. по умолчанию это None. 19.11.2012

  • 4

    Работая с огромным объемом данных, вы можете захотеть где-то их сохранить, поэтому какая-то база данных и ORM (например), но последнее - дело вкуса. Решением может быть своего рода СУБД.

    Что касается необработанного python, нет встроенного решения, кроме функциональных подпрограмм, таких как filter. В любом случае вы сталкиваетесь с итерацией на каком-то этапе (неявно или нет).

    Самый простой способ - сохранить дополнительный dict с ключами в качестве значений атрибутов:

    objectsBy['morphology'] = {'complex': set(), 'simple': set()}
    
    for item in sources:
      ...
      objMorphology = compute_morphology(item)
      objectsBy['morphology'][objMorphology] += item
      ...
    
    19.11.2012
    Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

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

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...