Самый быстрый способ проверить, существует ли значение в списке

Одно ленивое и простое решение

Предположим, что ваш шаблон регулярного выражения split_pattern = r'(!|\?)'

Сначала вы добавляете тот же символ, что и новый разделитель, например '[cut]'

new_string = re.sub(split_pattern, '\\1[cut]', your_string)

Затем вы разделите новый разделитель, new_string.split('[cut]')

680
задан Peter Mortensen 11 May 2019 в 01:48
поделиться

2 ответа

Исходный вопрос был:

, Что состоит в том, чтобы знать самый быстрый путь, существует ли значение в списке (список с миллионами значений в нем) и каков его индекс?

Таким образом существует две вещи найти:

  1. объект в списке, и
  2. , каков индекс (если в списке).

К этому, я изменил код @xslittlegrass для вычислений индексов во всех случаях и добавил дополнительный метод.

Результаты

enter image description here

Методы:

  1. в - в основном, если x в b: возвратите b.index (x)
  2. , попытка - пробует/завоевывает популярность b.index (x) (пропуски, имеющие необходимость проверять если x в b)
  3. набор - в основном если x в наборе (b): возвратитесь b.index (x)
  4. делят пополам - вид b с его индексом, двоичным поиском x в отсортированном (b). Отметьте модификацию в @xslittlegrass, кто возвращает индекс в отсортированном b, а не исходный реверс b)
  5. - формирует обратный цикл словарь d для b; затем d [x] обеспечивает индекс x.

, Результаты показывают, что метод 5 является самым быстрым.

Интересно попытка и установила , методы эквивалентны вовремя.

<час>

Тестовый код

import random
import bisect
import matplotlib.pyplot as plt
import math
import timeit
import itertools

def wrapper(func, *args, **kwargs):
    " Use to produced 0 argument function for call it"
    # Reference https://www.pythoncentral.io/time-a-python-function/
    def wrapped():
        return func(*args, **kwargs)
    return wrapped

def method_in(a,b,c):
    for i,x in enumerate(a):
        if x in b:
            c[i] = b.index(x)
        else:
            c[i] = -1
    return c

def method_try(a,b,c):
    for i, x in enumerate(a):
        try:
            c[i] = b.index(x)
        except ValueError:
            c[i] = -1

def method_set_in(a,b,c):
    s = set(b)
    for i,x in enumerate(a):
        if x in s:
            c[i] = b.index(x)
        else:
            c[i] = -1
    return c

def method_bisect(a,b,c):
    " Finds indexes using bisection "

    # Create a sorted b with its index
    bsorted = sorted([(x, i) for i, x in enumerate(b)], key = lambda t: t[0])

    for i,x in enumerate(a):
        index = bisect.bisect_left(bsorted,(x, ))
        c[i] = -1
        if index < len(a):
            if x == bsorted[index][0]:
                c[i] = bsorted[index][1]  # index in the b array

    return c

def method_reverse_lookup(a, b, c):
    reverse_lookup = {x:i for i, x in enumerate(b)}
    for i, x in enumerate(a):
        c[i] = reverse_lookup.get(x, -1)
    return c

def profile():
    Nls = [x for x in range(1000,20000,1000)]
    number_iterations = 10
    methods = [method_in, method_try, method_set_in, method_bisect, method_reverse_lookup]
    time_methods = [[] for _ in range(len(methods))]

    for N in Nls:
        a = [x for x in range(0,N)]
        random.shuffle(a)
        b = [x for x in range(0,N)]
        random.shuffle(b)
        c = [0 for x in range(0,N)]

        for i, func in enumerate(methods):
            wrapped = wrapper(func, a, b, c)
            time_methods[i].append(math.log(timeit.timeit(wrapped, number=number_iterations)))

    markers = itertools.cycle(('o', '+', '.', '>', '2'))
    colors = itertools.cycle(('r', 'b', 'g', 'y', 'c'))
    labels = itertools.cycle(('in', 'try', 'set', 'bisect', 'reverse'))

    for i in range(len(time_methods)):
        plt.plot(Nls,time_methods[i],marker = next(markers),color=next(colors),linestyle='-',label=next(labels))

    plt.xlabel('list size', fontsize=18)
    plt.ylabel('log(time)', fontsize=18)
    plt.legend(loc = 'upper left')
    plt.show()

profile()
1
ответ дан 22 November 2019 в 21:30
поделиться

Это работало на меня: (перечислите понимание, остроту)

[list_to_search_in.index(i) for i in list_from_which_to_search if i in list_to_search_in]

я имел list_to_search_in со всеми объектами и хотел возвратить индексы объектов в list_from_which_to_search.

Это возвращает индексы в хорошем списке.

0
ответ дан 22 November 2019 в 21:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: