Извлечение кортежа из коллекции кортежей на основе содержащегося значения - PullRequest
0 голосов
/ 26 июня 2009

У меня есть структура данных, которая представляет собой набор таких кортежей:

things = ( (123, 1, "Floogle"), (154, 33, "Blurgle"), (156, 55, "Blarg") )

Первый и третий элементы являются уникальными для коллекции.

Что я хочу сделать, так это получить определенный кортеж, ссылаясь на третье значение, например:

>>> my_thing = things.get( value(3) == "Blurgle" )
(154, 33, "Blurgle")

Должен быть лучший способ, чем писать цикл, чтобы проверять каждое значение одно за другим!

Ответы [ 3 ]

4 голосов
/ 26 июня 2009

Цикл (или что-то на 100% эквивалентное, например, понимание списка или genexp) - действительно единственный подход, если ваша структура внешнего уровня является кортежем, как вы указываете - по преднамеренному замыслу кортежи являются чрезвычайно легкими контейнер, практически без каких-либо методов (только несколько специальных методов, необходимых для реализации индексации, циклического выполнения и т. п .; -).

Молниеносный поиск является характеристикой словарей, а не кортежей. Разве у вас нет словаря (в качестве основной или вспомогательной структуры), который сопоставляет «значение третьего элемента» с искомым поднабором (или, возможно, с его индексом в основном кортеже)? Это можно построить с помощью одного цикла, а затем выполнить столько быстрых поисков, сколько вам нужно!

Если вы решите зациклить, Genexp, согласно комментарию Брайана и моего ответа на него, будет более читабельным и в среднем может быть в два раза быстрее, чем listcomp (так как он выполняет только половину цикла):

my_thing = next(item for item in things if item[2] == "Blurgle")

, который читается как «следующий элемент в вещах, чей [2] подэлемент равен Blurgle» (когда вы начинаете с начала, «следующий» элемент, который вы найдете, будет «первым»), и, в твой случай, только - подходящий).

Если вам нужно охватить случай, когда ни один элемент не соответствует предикату, вы можете передать next второй аргумент (который он будет возвращать при необходимости), в противном случае (без второго аргумента, как в моем фрагменте) вы ' Я получу исключение StopIteration, если ни один элемент не соответствует предикату - любое поведение может быть тем, что вы хотите (как вы говорите, случай не должен возникать, исключение выглядит подходящим для вашего конкретного приложения, поскольку рассматриваемое вхождение было бы неожиданной ошибкой) .

1 голос
/ 26 июня 2009

если вам придется выполнять поиск такого типа несколько раз, почему бы вам не преобразовать вещи в одно и то же в один раз, тогда поиск будет проще и быстрее выполнить

things = ( (123, 1, "Floogle"), (154, 33, "Blurgle"), (156, 55, "Blarg") )

things_dict = {}
for t in things:
    things_dict[t[2]] = t

print things_dict['Blarg']
1 голос
/ 26 июня 2009

Если things - это список, и вы знаете, что третий элемент уникален, как насчет понимания списка?

>> my_thing = [x for x in things if x[2]=="Blurgle"][0]

Хотя под капотом, я предполагаю, что проходит все значения и проверяет их индивидуально. Если вам это не нравится, как насчет изменения структуры my_things, чтобы она стала dict и использования в качестве ключа первого или третьего значения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...