Сведения о вопросе

Henry

16:03, 1st July, 2020

Теги

python   arrays   iteration    

Использование 'in' для сопоставления атрибута объектов Python в массиве

Просмотров: 509   Ответов: 8

Я не помню, спал я или нет, но я, кажется, помню, что была функция, которая позволяла что-то вроде,

foo in iter_attr(array of python objects, attribute name)

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



  Сведения об ответе

SSESION

18:03, 1st July, 2020

Используя понимание списка, вы создадите временный список, который может съесть всю вашу память, если искомая последовательность будет большой. Даже если последовательность невелика, построение списка означает повторение всей последовательности до того, как in сможет начать ее поиск.

Временный список можно избежать с помощью выражения генератора:

foo = 12
foo in (obj.id for obj in bar)

Теперь , пока obj.id == 12 находится рядом с началом bar, поиск будет быстрым, даже если bar бесконечно длинен.

Как было предложено @Matt, рекомендуется использовать hasattr , если какой-либо из объектов в bar может отсутствовать атрибут id :

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))


  Сведения об ответе

dumai

18:03, 1st July, 2020

Вы хотите получить список объектов, которые имеют определенный атрибут? Если это так, то понимание списка -правильный способ сделать это.

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]


  Сведения об ответе

piter

18:03, 1st July, 2020

вы всегда можете написать его сами:

def iterattr(iterator, attributename):
    for obj in iterator:
        yield getattr(obj, attributename)

будет работать со всем, что повторяется, будь то кортеж, список или что-то еще.

Я люблю python, это делает вещи, как это очень просто и не более хлопот, чем необходимо, и в использовании вещи, как это чрезвычайно элегантно.


  Сведения об ответе

+-*/

18:03, 1st July, 2020

Нет, это был не сон. Python имеет довольно отличную систему понимания списков, которая позволяет вам довольно элегантно манипулировать списками, и в зависимости от того, что именно вы хотите сделать, это можно сделать несколькими способами. По сути, то, что вы делаете, говорит "для элемента в списке if criteria.matches", и от этого вы можете просто перебирать результаты или сбрасывать результаты в новый список.

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

    files = os.listdir(path)                               
    test = re.compile("test\.py$", re.IGNORECASE)          
    files = [f for f in files if test.search(f)]

Вы можете сделать это без регулярных выражений, например, для всего, где ваше выражение в конце возвращает true для совпадения. Есть и другие варианты, такие как использование функции filter(), но если бы я собирался выбрать, я бы пошел с этим.

Эрик Сиппл


  Сведения об ответе

ASER

18:03, 1st July, 2020

Функция, о которой вы думаете, вероятно, operator.attrgettter . Например, чтобы получить список, содержащий значение атрибута "id" каждого объекта:

import operator
ids = map(operator.attrgetter("id"), bar)

Если вы хотите проверить, содержит ли список объект с идентификатором = = 12, то аккуратный и эффективный (т. е. не повторяет весь список без необходимости) способ сделать это::

any(obj.id == 12 for obj in bar)

Если вы хотите использовать 'in' с attrgetter, сохраняя при этом ленивую итерацию списка:

import operator,itertools
foo = 12
foo in itertools.imap(operator.attrgetter("id"), bar)


  Сведения об ответе

crush

18:03, 1st July, 2020

То, о чем я думал, может быть достигнуто с помощью понимания списка, но я думал, что есть функция, которая делает это немного более аккуратным способом.

т. е. 'bar'-это список объектов, каждый из которых имеет атрибут 'id'

Мифический функциональный путь:

foo = 12
foo in iter_attr(bar, 'id')

Способ понимания списка:

foo = 12
foo in [obj.id for obj in bar]

В ретроспективе способ понимания списка довольно аккуратен в любом случае.


  Сведения об ответе

VERSUION

18:03, 1st July, 2020

Если вы планируете искать что-нибудь отдаленно приличного размера, то лучше всего будет использовать словарь или набор. В противном случае вам в основном придется перебирать каждый элемент итератора, пока вы не доберетесь до нужного вам элемента.

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

Помните, что python имеет один из самых эффективных алгоритмов хэширования. Используй это в своих интересах.


  Сведения об ответе

baggs

18:03, 1st July, 2020

Я думаю:

#!/bin/python
bar in dict(Foo)

Это то, о чем вы думаете. При попытке проверить, существует ли определенный ключ в словаре в python (версия python таблицы hash), есть два способа проверить. Во-первых, это метод has_key() , прикрепленный к словарю, а во-вторых, приведенный выше пример. Он вернет логическое значение.

Это должно ответить на ваш вопрос.

А теперь немного отвлечемся от темы, чтобы привязать это к списку понимания ответа, который был дан ранее (для большей ясности). Понимание списка постройте список из базового цикла for с модификаторами. В качестве примера (чтобы немного прояснить), способ использования языковой конструкции in dict в понимании списка :

Допустим, у вас есть двумерный словарь foo , и вам нужны только словари второго измерения, содержащие ключ bar . Относительно простым способом сделать это было бы использовать понимание списка с условным следующим образом:

#!/bin/python
baz = dict([(key, value) for key, value in foo if bar in value])

Обратите внимание на if bar in value в конце statement**, это модифицирующее предложение, которое говорит пониманию списка сохранять только те пары ключ-значение, которые соответствуют условию.** В этом случае baz -это новый словарь, который содержит только словари из foo, которые содержат bar (надеюсь, я ничего не пропустил в этом примере кода... возможно , вам придется взглянуть на документацию по пониманию списка, найденную в docs.python.org учебниках и в secnetix.de, оба сайта являются хорошими ссылками, если у вас возникнут вопросы в будущем.).


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться