Python: извлечение списков из списка с модулем или регулярным выражением

Подумайте о 0 как false и 1 как истина. Затем побитовые и (& amp;) и / или (|) работают так же, как и обычные, и / или только за исключением того, что все биты в значении сразу. Как правило, вы увидите, что они используются для флагов, если у вас есть 30 параметров, которые можно установить (например, стили рисования в окне), которые вы не хотите передавать в 30 отдельных логических значениях, чтобы установить или отключить их, чтобы вы использовали | для объединения опций в одно значение, а затем вы используете & amp; чтобы проверить, установлена ​​ли каждая опция. Этот стиль прохождения флага сильно используется OpenGL. Поскольку каждый бит является отдельным флагом, вы получаете значения флага по степеням двух (или числа, которые имеют только один бит) 1 (2 ^ 0) 2 (2 ^ 1) 4 (2 ^ 2) 8 (2 ^ 3) мощность двух указывает, какой бит установлен, если флаг включен.

Также обратите внимание на 2 = 10, так что x | 2 равно 110 (6) не 111 (7) Если ни один из битов не перекрывается (что true в этом случае) | действует как дополнение.

6
задан baconLX 13 July 2018 в 14:49
поделиться

6 ответов

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

import re

def find_span(numbers, start, end):
    # Create strings from the start and end lists.
    start_pattern = ''.join(map(chr, start))
    end_pattern = ''.join(map(chr, end))

    # convert the list to search into one string.
    s = ''.join(map(chr, numbers))

    # Create a pattern that starts and ends with the correct sublists,
    # and match all sublists. Then convert each match back to a list of
    # integers
    # The '?' is to make the regex non-greedy
    return [
        [ord(c) for c in match]
        for match in re.findall(rf'{start_pattern}.*?{end_pattern}', s, re.DOTALL)
    ]

>>> find_span(search, start, end)  # Using OP's sample values
[[1, 2, 3, 99, 99, 99, 4, 5, 6], [1, 2, 3, 99, 4, 5, 6]]

Обратите внимание, что это не очень эффективно, поскольку для этого требуется динамическое построение regex каждый раз, когда он вызывается. И вам нужно использовать re.DOTALL, потому что иначе он не будет соответствовать ничему, содержащему 10 (который является ascii-кодировкой новой строки). Однако, если вы действительно хотите использовать регулярные выражения , это сработает.

1
ответ дан Edward Minnix 17 August 2018 в 12:34
поделиться
  • 1
    сначала используйте карту для преобразования int в str. Вы уверены, что он дает ожидаемый результат, опубликованный OP? Я пытался повторное выражение, но не мог избавиться от некоторых перекрытий – mad_ 13 July 2018 в 15:41
  • 2
    – Edward Minnix 13 July 2018 в 15:50
  • 3
    можете ли вы также опубликовать вывод? Просто хочу знать, что я делаю неправильно. Поблагодарите его. благодаря – mad_ 13 July 2018 в 15:55
  • 4
    – Edward Minnix 13 July 2018 в 16:02
  • 5

Вот подход itertools, который использует ограниченную длину collections.deque, чтобы сохранить буфер последних элементов соответствующего размера. Предполагается, что ваши подсписки не перекрываются и что ваши начальные и конечные последовательности не перекрываются.

Он работает для любой последовательности для данных, начала, конца (даже генераторы).

from collections import deque
from itertools import islice

def sublists(data, start, end):
    it = iter(data)
    start, end = deque(start), deque(end)
    while True:
        x = deque(islice(it, len(start)), len(start))
        # move forward until start is found
        while x != start:
            x.append(next(it))
        out = list(x)
        x = deque(islice(it, len(end)), len(end))
        # move forward until end is found, storing the sublist
        while x != end:
            out.append(x[0])
            x.append(next(it))
        out.extend(end)
        yield out

data = [99, 99, 1, 2, 3, 99, 99, 99, 4, 5, 6, 99, 99, 1, 2, 3, 99, 4, 5, 6, 99]

startSequence = [1,2,3]
endSequence = [4,5,6]

print(list(sublists(data, startSequence, endSequence)))
# [[1, 2, 3, 99, 99, 99, 4, 5, 6], [1, 2, 3, 99, 4, 5, 6]]
2
ответ дан Graipher 17 August 2018 в 12:34
поделиться

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

Мы сохраняем deque размер start пока мы не встретим его. Затем мы добавляем эти значения в список и продолжаем повторять последовательность. Как и мы, мы сохраняем deque размер конечной последовательности, пока не увидим ее, а также добавим элементы в список, который мы сохраняем. Если мы сталкиваемся с конечной последовательностью, мы yield, которые перечислили и установили deque для сканирования следующей стартовой последовательности.

from collections import deque

def gen(l, start, stop):
    start_deque = deque(start)
    end_deque = deque(stop)
    curr_deque = deque(maxlen=len(start))
    it = iter(l)
    for c in it:
        curr_deque.append(c)
        if curr_deque == start_deque:
            potential = list(curr_deque)
            curr_deque = deque(maxlen=len(stop))
            for c in it:
                potential.append(c)
                curr_deque.append(c)
                if curr_deque == end_deque:
                    yield potential
                    curr_deque = deque(maxlen=len(start))
                    break

print(list(gen([99, 99, 1, 2, 3, 99, 99, 99, 4, 5, 6, 99, 99, 1, 2, 3, 99, 4, 5, 6, 99], [1,2,3], [4,5,6])))

# [[1, 2, 3, 99, 99, 99, 4, 5, 6], [1, 2, 3, 99, 4, 5, 6]]
3
ответ дан Patrick Haugh 17 August 2018 в 12:34
поделиться

Используйте метод ниже:

def find_sub_list(sl,l):
    sll=len(sl)
    for ind in (i for i,e in enumerate(l) if e==sl[0]):
        if l[ind:ind+sll]==sl:
            return ind,ind+sll-1

find_sub_list([1,2,3], data)    
>>>(2, 4)
find_sub_list([4,5,6], data)    
>>>(8, 10)

data[2:10+1]
>>>[1, 2, 3, 99, 99, 99, 4, 5, 6]

Вы можете использовать аналогичный подход для sublists[1]

Предоставлено: find-start-and-end-index-of- подсписок-в-списке

0
ответ дан Prateek 17 August 2018 в 12:34
поделиться

Здесь находится решение O (n), которое находит совпадения, отслеживая соответствие шаблонов startSequence и endSequence

def myFunctionForSublists(data, startSequence, endSequence):
    start,end = tuple(startSequence), tuple(endSequence)
    l1, l2    = len(start), len(end)
    s = -1
    result = []
    for i,v in enumerate(zip(*[data[i:] for i in range(0,l1)])):
        if v == start:
            s = i
        if v == end and s != -1:
            result.append(data[s:i+l2])
            s = -1

    return result


print (myFunctionForSublists(data, startSequence, endSequence))
# [[1, 2, 3, 99, 99, 99, 4, 5, 6], [1, 2, 3, 99, 4, 5, 6]]
0
ответ дан Sunitha 17 August 2018 в 12:34
поделиться

Просто переберите все в индексы в списке и сравните срез с startSequence или endSequence, соответственно. Предполагая, что подписи не должны перекрываться, вы можете использовать один и тот же итератор для обоих циклов.

def myFunctionForSublists(data, startSequence, endSequence):
    positions = iter(range(len(data)))
    for start in positions:
        if data[start:start+len(startSequence)] == startSequence:
            for end in positions:
                if data[end:end+len(endSequence)] == endSequence:
                    yield data[start:end+len(endSequence)]
                    break

Таким образом, цикл start будет продолжаться, когда петля end будет оставаться. Если они могут перекрывать , используйте два отдельных итератора для цикла, то есть for start in range(len(data)): и for end in range(start+1, len(data)):

0
ответ дан tobias_k 17 August 2018 в 12:34
поделиться
Другие вопросы по тегам:

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