Наконец-то нашел то, что искал, используя только RE lib:
поиск текста и получение значения возле searchkey
words = re.findall(r'\w+', contentwhereyouwanttosearchinside)
index = words.index('SEARCHKEY')
напечатать следующие 3 слово например возле ключа поиска
value1 = words[index + 1:index + 3]
print(value1)
Я запустил бы путем записи метода генератора:
def grid_objects(alist, blist):
for i in range(len(alist)):
for j in range(len(alist[i])):
yield(alist[i][j], blist[i][j])
Тогда каждый раз, когда необходимо выполнить итерации по спискам, код похож на это:
for (a, b) in grid_objects(alist, blist):
if a.is_whatever():
b.do_something()
Если кто-либо интересуется производительностью вышеупомянутых решений, здесь они для 4000x4000 сетки от самого быстрого до самого медленного:
izip
вместо zip
) zip
) РЕДАКТИРОВАНИЕ : очки Добавленного Brian с izip
модификация и выигранный большой суммой!
решение John's также очень быстро, хотя оно использует индексы (я был действительно удивлен видеть это!), тогда как Robert и Brian (с zip
) медленнее, чем начальное решение создателя вопроса.
Так позволяют нам представить функция завоевания Brian, поскольку ее не показывают в надлежащей форме нигде в этом потоке:
from itertools import izip
for a_row,b_row in izip(alist, blist):
for a_item, b_item in izip(a_row,b_row):
if a_item.isWhatever:
b_item.doSomething()
Вы могли архивировать их. т.е.:
for a_row,b_row in zip(alist, blist):
for a_item, b_item in zip(a_row,b_row):
if a_item.isWhatever:
b_item.doSomething()
Однако издержки архивирования и итерации по объектам могут быть выше, чем Ваш исходный метод, если Вы редко на самом деле используете b_item (т.е. a_item.isWhatever обычно является Ложь). Вы могли использовать itertools.izip вместо zip для сокращения влияния памяти этого, но его все еще, вероятно, попытка быть немного медленнее, если Вам всегда не нужен b_item.
, С другой стороны, рассматривают использование 3D списка вместо этого, таким образом, ландшафт для ячейки i, j в l [я] [j] [0], возражает в l [я] [j][1] и т.д., или даже объедините объекты, таким образом, можно сделать [я] [j] .terrain, [я] [j] .object и т.д.
[Редактирование] синхронизации DzinX на самом деле шоу, что влияние дополнительной проверки на b_item не является действительно значительным, рядом с потерей производительности перевзгляда индексом, таким образом, вышеупомянутое (использующий izip), кажется, является самым быстрым.
я теперь дал быстрый тест для 3-го подхода также, и кажется быстрее все еще, поэтому если можно хранить данные в той форме, это могло бы быть и более простым и быстрее к доступу. Вот пример использования его:
# Initialise 3d list:
alist = [ [[A(a_args), B(b_args)] for i in xrange(WIDTH)] for j in xrange(HEIGHT)]
# Process it:
for row in xlist:
for a,b in row:
if a.isWhatever():
b.doSomething()
Вот мои синхронизации для 10 циклов с помощью 1000x1000 массив с различными пропорциями isWhatever, который быть верным:
( Chance isWhatever is True )
Method 100% 50% 10% 1%
3d 3.422 2.151 1.067 0.824
izip 3.647 2.383 1.282 0.985
original 5.422 3.426 1.891 1.534
Когда Вы действуете с сетками чисел и хотите действительно хорошую производительность, необходимо рассмотреть использование Numpy. Это удивительно просто в использовании и позволяет Вам думать с точки зрения операций с сетками вместо циклов по сеткам. Производительность прибывает из того, что операции тогда выполняются по целым сеткам с оптимизированным кодом SSE.
, Например, вот некоторый numpy, использующий код, что я записал, что это делает численное моделирование грубой силы заряженных частиц, соединенных пружинами. Этот код вычисляет такт для 3-й системы с 100 узлами и 99 краями в 31 мс. Это по 10x быстрее, чем лучший чистый код Python, который я мог придумать.
from numpy import array, sqrt, float32, newaxis
def evolve(points, velocities, edges, timestep=0.01, charge=0.1, mass=1., edgelen=0.5, dampen=0.95):
"""Evolve a n body system of electrostatically repulsive nodes connected by
springs by one timestep."""
velocities *= dampen
# calculate matrix of distance vectors between all points and their lengths squared
dists = array([[p2 - p1 for p2 in points] for p1 in points])
l_2 = (dists*dists).sum(axis=2)
# make the diagonal 1's to avoid division by zero
for i in xrange(points.shape[0]):
l_2[i,i] = 1
l_2_inv = 1/l_2
l_3_inv = l_2_inv*sqrt(l_2_inv)
# repulsive force: distance vectors divided by length cubed, summed and multiplied by scale
scale = timestep*charge*charge/mass
velocities -= scale*(l_3_inv[:,:,newaxis].repeat(points.shape[1], axis=2)*dists).sum(axis=1)
# calculate spring contributions for each point
for idx, (point, outedges) in enumerate(izip(points, edges)):
edgevecs = point - points.take(outedges, axis=0)
edgevec_lens = sqrt((edgevecs*edgevecs).sum(axis=1))
scale = timestep/mass
velocities[idx] += (edgevecs*((((edgelen*scale)/edgevec_lens - scale))[:,newaxis].repeat(points.shape[1],axis=1))).sum(axis=0)
# move points to new positions
points += velocities*timestep
Как небольшое изменение стиля, Вы могли использовать, перечислите:
for i, arow in enumerate(alist):
for j, aval in enumerate(arow):
if aval.isWhatever():
blist[i][j].doSomething()
я не думаю, что Вы получите что-либо значительно более простое, если Вы не перестроите свои структуры данных, как Federico предполагает. Так, чтобы Вы могли превратить последнюю строку во что-то как "aval.b.doSomething ()".
выражения и izip
Генератора от [1 111] itertools модуль сделает очень приятно здесь:
from itertools import izip
for a, b in (pair for (aline, bline) in izip(alist, blist)
for pair in izip(aline, bline)):
if a.isWhatever:
b.doSomething()
строка в for
оператор выше средств:
alist
и blist
и делают кортеж от них (aline, bline)
izip
снова и берут каждый элемент от них (pair
). Этот метод имеет два преимущества:
zip
и использовать более эффективные генераторы с izip
вместо этого. Вы уверены, что объекты в этих двух матрицах, которых Вы выполняете итерации параллельно, являются экземплярами концептуально отличных классов? Что относительно того, чтобы объединить эти два класса, заканчивающиеся с матрицей объектов, которые содержат оба isWhatever () и doSomething ()?
Если эти два 2D списка остаются постоянными в течение времени жизни Вашей игры и , Вы не можете наслаждаться множественным наследованием Python для присоединения к alist [я] [j] и blist [я] [j] классы объектов (как другие предположили), Вы могли добавить указатель на соответствие объект b в каждом объект после того, как списки создаются, как это:
for a_row, b_row in itertools.izip(alist, blist):
for a_item, b_item in itertools.izip(a_row, b_row):
a_item.b_item= b_item
Различные оптимизации могут применяться здесь, как Ваши классы, определяющие __slots__
, или код инициализации выше мог быть объединен с Вашим собственным e.t.c кода инициализации. После этого Ваш цикл станет:
for a_row in alist:
for a_item in a_row:
if a_item.isWhatever():
a_item.b_item.doSomething()
, Который должен быть более эффективным.
Если a.isWhatever
редко верно, что Вы могли бы создать "индекс" однажды:
a_index = set((i,j)
for i,arow in enumerate(a)
for j,a in enumerate(arow)
if a.IsWhatever())
и каждый раз Вы хотите, чтобы что-то было сделано:
for (i,j) in a_index:
b[i][j].doSomething()
, Если изменения со временем, то необходимо будет усовершенствовать индекс. Вот почему я использовал набор, таким образом, объекты могут быть добавлены и удалены быстро.
for d1 in alist
for d2 in d1
if d2 = "whatever"
do_my_thing()