Найти структуру кортежа, содержащую неизвестное значение внутри списка

Скажем, у меня есть список кортежей:

list = [(1,5), (1,7), (2,3)] 

Есть ли способ в Python написать что-то вроде

 if (1, *) in list: do things 

где * означает « Меня не волнует эта ценность »? Поэтому мы проверяем, есть ли кортеж с 1 в первой позиции и с любым значением на втором.

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

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

7 Solutions collect form web for “Найти структуру кортежа, содержащую неизвестное значение внутри списка”

Объект-заполнитель, как вы просите, не поддерживается изначально, но вы можете сделать что-то подобное:

 class Any(object): def __eq__(self, other): return True ANYTHING = Any() lst = [(1,5), (1,7), (2,3)] 

Метод __eq__ определяет, как два объекта проверяют равенство. (Подробнее см. https://docs.python.org/3/reference/datamodel.html .) Здесь ANYTHING всегда будет проверять положительный результат на равенство с любым объектом. (Если этот объект также не __eq__ , чтобы вернуть False.)

Оператор in просто вызывает __eq__ для каждого элемента в вашем списке. Т.е. a in b делает что-то вроде:

 for elem in b: if elem == a: return True 

Это означает, что если вы скажете (1, ANYTHING) in lst , Python сначала сравнит (1, ANYTHING) с первым элементом в lst . (Tuples, в свою очередь, определяют __eq__ для возврата True, если все его элементы « __eq__ возвращают True». Ie (x, y) == (a, b) эквивалентно x==a and y==b или x.__eq__(a) and y.__eq__(b) .)

Следовательно, (1, ANYTHING) in lst вернет True, а (3, ANYTHING) in lst вернет False.

Также обратите внимание, что я переименовал ваш список lst вместо list чтобы предотвратить конфликты имен с встроенным list Python.

Вы можете использовать функцию any() :

 if any(t[0] == 1 for t in yourlist): 

Это эффективно проверяет и выходит раньше, если 1 находится в первой позиции кортежа.

Не все мои методы решения, приведенные ниже, будут обязательно эффективными. Моя цель – продемонстрировать все возможные способы решения, о которых я могу думать, – в конце моего ответа я предоставляю результаты «теста», чтобы показать, почему или почему вы не должны использовать один определенный метод над другим. Я считаю, что это хороший способ обучения, и я буду бесстыдно поощрять такое обучение в своих ответах.


Подмножество + хэш- set s

 >>> a_list = [(1,5), (1,7), (2,3)] >>> >>> set([l[0] for l in a_list]) {1, 2} >>> >>> 1 in set([l[0] for l in a_list]) True 

map() и анонимные функции

 >>> a_list = [(1,5), (1,7), (2,3)] >>> >>> map(lambda x: x[0] == 1, a_list) [True, True, False] >>> >>> True in set(map(lambda x: x[0] == 1, a_list)) True 

filter и анонимные функции

 >>> a_list = [(1,5), (1,7), (2,3)] >>> >>> filter(lambda x: x[0] == 1, a_list) [(1,5), (1,7)] >>> >>> len(filter(lambda x: x[0] == 1, a_list)) > 0 # non-empty list True 

MICROBENCHMARKS

условия

  • 1000 наименований
  • Повторение 100 тыс.
  • 0-100 случайный диапазон
  • Python 2.7.10, IPython 2.3.0

скрипт

 from pprint import pprint from random import randint from timeit import timeit N_ITEMS = 1000 N_SIM = 1 * (10 ** 5) # 100K = 100000 a_list = [(randint(0, 100), randint(0, 100)) for _ in range(N_ITEMS)] set_membership_list_comprehension_time = timeit( "1 in set([l[0] for l in a_list])", number = N_SIM, setup="from __main__ import a_list" ) bool_membership_map_time = timeit( "True in set(map(lambda x: x[0] == 1, a_list))", number = N_SIM, setup="from __main__ import a_list" ) nonzero_length_filter_time = timeit( "len(filter(lambda x: x[0] == 1, a_list)) > 0", number = N_SIM, setup="from __main__ import a_list" ) any_list_comprehension_time = timeit( "any(t[0] == 1 for t in a_list)", number = N_SIM, setup="from __main__ import a_list" ) results = { "any(t[0] == 1 for t in a_list)": any_list_comprehension_time, "len(filter(lambda x: x[0] == 1, a_list)) > 0": nonzero_length_filter_time, "True in set(map(lambda x: x[0] == 1, a_list))": bool_membership_map_time, "1 in set([l[0] for l in a_list])": set_membership_list_comprehension_time } pprint( sorted(results.items(), key = lambda x: x[1]) ) 

Результаты (в секундах)

 [('any(t[0] == 1 for t in a_list)', 2.6685791015625), # winner - Martijn ('1 in set([l[0] for l in a_list])', 4.85234808921814), ('len(filter(lambda x: x[0] == 1, a_list)) > 0', 7.11224889755249), ('True in set(map(lambda x: x[0] == 1, a_list))', 10.343087911605835)] 

Кто сейчас смеется? … Martijn (по крайней мере, я пробовал)

MORAL OF THE STORY: не тратьте больше 10 минут, «доказывая», что ваше плохое решение быстрее и эффективнее на небольших тестовых данных, когда ответ другого пользователя является де-факто правильным

Это можно сделать в Python, используя понимание списка. например:

 a= [(1, 2), (3, 4), (4, 5), (1, 4)] [i for i in a if i[0] == 1] 

Дам тебе:

 [(1, 2), (1, 4)] 

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

 In [3]: [a for a,*_ in l] Out[3]: [1, 1, 2] 

Или с любой логикой:

 In [4]: l = [(1,5), (1,7), (2,3)] In [5]: any(a == 1 for a,*_ in l) Out[5]: True 

Или имитировать любой без вызова функции:

 In [23]: l = [(1,5), (1,7), (2,3)] In [24]: g = (a for a,*_ in l) In [25]: 1 in g Out[25]: True In [26]: list(g) Out[26]: [1, 2] 

Также можно было бы обрабатывать количество элементов в кортеже.

 >>> import operator >>> mylist = [(1,2), (1,5), (4,5,8)] >>> any(i==1 for i in map(operator.itemgetter(0), mylist)) True 

Похоже, вы действительно хотите filter() , а не any() :

 tuple_list = [(1,5), (1,7), (2,3)] for pair in filter(lambda pair: (pair[0] == 1), tuple_list): print "Second value {pair[1]} found from {pair}".format(pair=pair) ... Second value 5 found from (1, 5) Second value 7 found from (1, 7) 

Метод filter () велик, потому что вы можете напрямую предоставить ему функцию. Это позволяет указать определенный ключ для фильтрации и т. Д. Чтобы упростить его, используйте выражение лямбда, чтобы превратить всю вещь в однострочный.

  • python удаление пробела из строки в списке
  • В python, что делает len (list)?
  • Как спрятать hetrogenous список списка в один список в python?
  • разделять элементы списка в python
  • Python проверяет первый и последний индекс списка
  • Как подсчитать количество уникальных списков в списке?
  • Максимальное значение в списке списков кортежей
  • Различное поведение для списка .__ iadd__ и list .__ add__
  • TypeError: объект 'list' не вызывается в python
  • Сумма из нескольких списков индексов
  • Python - Итерирование по списку списка
  •  
    Interesting Posts for Van-Lav

    boost :: python: компиляция завершается с ошибкой, поскольку конструктор копирования является закрытым

    Проверка соединения SSL с помощью python

    Как использовать django-компрессор за балансиром нагрузки?

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

    NumPy, умножающее int на float, похоже, не работает

    Какой подход вы использовали для легких модульных тестов Python в App Engine?

    Python urlparse – вырезать доменное имя без субдомена

    Могут ли события SQLAlchemy использоваться для обновления денормализованного кэша данных?

    запуск PIL на 64-битной

    json.loads (jsonstring) в Python терпит неудачу, если строка имеет символ «\ r», т.е. символ возврата каретки

    Модуль DSA в Python

    превратить смешанный список в строку, сохранить кавычки только для строк

    Как программно получить местоположение python.exe?

    DateTimeField получил наивное datetime

    Хороший pythonic способ определить выбор полей модели django с дополнительными атрибутами и методами

    Python - лучший язык программирования в мире.