2014-09-24 3 views
0

У меня есть набор из ~ 10 миллионов предметов, которые выглядят примерно так:Как найти элемент с определенной начальной строкой в ​​наборе

1234word:something 
4321soup:ohnoes 
9cake123:itsokay 
[...] 

Теперь мне нужно быстро проверить, если элемент с А конкретный старт находится в наборе. Например

x = "4321soup" 
is x+* in a_set: 
    print ("somthing that looks like " +x +"* is in the set!") 

Как это сделать? Я рассматривал использование регулярного выражения, но я не знаю, возможно ли это в этом сценарии.

+0

вы хотите напечатать строки, которая начинается с '4321soup'? –

+2

Head's up: если у вас действительно есть что-то вроде 10M записей в вашем наборе, вам может быть лучше с [trie] (http://en.wikipedia.org/wiki/Trie) – inspectorG4dget

+0

Я согласен с @ inspectorG4dget, python set не является хорошей структурой для такой задачи. Лучше использовать дерево или отсортированную последовательность, чтобы получить результат в 'O (log (n))' вместо O (n) time –

ответ

0
^4321soup.*$ 

Да это possible.Try match.If результат положителен у вас есть it.If это None вы не имеете его.

Не забудьте установить m и g флаги.

См. Демонстрационную версию.

http://regex101.com/r/lS5tT3/28

0

использование str.startswith вместо использования регулярных выражений, если вы хотите, чтобы соответствовать только с начала строки, а также с учетом количества строк у вас возникли ~ 10 миллионов пунктов

#!/usr/bin/python 

str = "1234word:something"; 
print str.startswith('1234'); 

питона , учитывая, что ваше содержимое находится внутри файла с именем «mycontentfile»

>>> with open("mycontentfile","r") as myfile: 
...  data=myfile.read() 
... 
>>> for item in data.split("\n"): 
...  if item.startswith("4321soup"): 
...    print item.strip() 
... 
4321soup:ohnoes 
+0

Почему вы предлагаете использовать '.startswith()' instad regex? просто потому, что он менее сложный или он также быстрее? Кроме того, как использовать '.startswith()' в 'is x in set:'? –

+0

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

+0

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

0

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

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

items = set(x.split(':')[0] for x in a_set) # a_set can be any iterable 

def is_in_the_set(x): 
    return x in items 

is_in_the_set("4321soup") # True 
+0

это выглядит неплохо, но в этом случае - если бы я правильно понял - мне пришлось бы сохранить полный набор дважды (один раз с двумя значениями «x: y' = a_set и один раз с« x' = только элементы »), которые будут расти слишком большой для количества записей, которые у меня есть. В настоящее время я думаю, что наиболее разумное решение было бы чем-то вроде сортированного дерева dicts (key = x и value = y), и дерево сортируется клавишами dicts. - не знаю, как это сделать –

0

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

a_set = set(['1234word:something','4321soup:ohnoes','9cake123:itsokay',]) #a huge set 
prefix = '4321soup' #prefix you want to search 
next(x for x in a_set if x.startswith(prefix), False) #pass a generator with the desired match condition, and invoke it until it exhaust (will return False) or until it find something 
0

В настоящее время я думал, что наиболее разумное решение было бы что-то вроде отсортированного дерева dicts (ключ = х и значения = у) и дерева отсортировано по клавишам dicts. - не догадывается, как сделать это, хотя - Дедал Mythos

Нет необходимости в дерева dicts ... только один словарь будет делать. Если у вас есть пар ключ: значение, хранящиеся в словаре, скажем itemdict, вы можете написать

x = "4321soup" 
if x in itemdict: 
    print ("something that looks like "+x+"* is in the set!") 
Смежные вопросы