eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: I have a polars.DataFrame like: data = pl.DataFrame({ "col1": [3, 2, 4, 7, 1, 10, 7], "col2": [3, 4, None, 1, None, 1, 9], "col3": [3, 1, None, None, None, None, 4], "col4": [None, 5, None, None, None, None, None], "col5": [None, None, None, None, None, None, None]}) ┌──────┬──────┬──────┬──────┬──────┐ │ col1 ┆ col2 ┆ col3 ┆ col4 ┆ col5 │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 ┆ i64 ┆ f32 │ ╞══════╪══════╪══════╪══════╪══════╡ │ 3 ┆ 3 ┆ 3 ┆ null ┆ null │ │ 2 ┆ 4 ┆ 1 ┆ 5 ┆ null │ │ 4 ┆ null ┆ null ┆ null ┆ null │ │ 7 ┆ 1 ┆ null ┆ null ┆ null │ │ 1 ┆ null ┆ null ┆ null ┆ null │ │ 10 ┆ 1 ┆ null ┆ null ┆ null │ │ 7 ┆ 9 ┆ 4 ┆ null ┆ null │ └──────┴──────┴──────┴──────┴──────┘  I want to create a new column that contains the rolling mode - but not based on one column and the respective row values within the window but on row values of all columns within the window. The nulls should be dropped and shouldn't appear in the resulting columns as a mode value. edit: I made some changes to the example data provided. For further clarifications and under the assumption of something like polars.rolling_apply(<function>, window_size=2, min_periods=1, center=False) I would expect the following result: ┌──────┐ │ res │ │ --- │ │ i64 │ ╞══════╡ │ 3 │ │ 3 │ │ 4 │ │ None │ <- all values different │ 1 │ │ 1 │ │ None │ <- all values different └──────┘  In case there is no mode None as a result would be fine. Only the missing value in the original polars.DataFrame should be ignored.

Answer: .rolling() can be used to aggregate over the windows. Using .concat_list() inside .agg() will give us a nested list, e.g.  [[col1, col2, ...], [col1, col2, ...]]  Which we can flatten, remove nulls, and calculate the mode.  .flatten() .drop_nulls() .mode()  (df.with_row_index() .rolling( index_column = "index", period = "2i" ) .agg( pl.concat_list(pl.exclude("index")).flatten().drop_nulls().mode() .alias("mode") ) # .with_columns( # pl.when(pl.col("mode").list.len() == 1) # .then(pl.col("mode").list.first()) # ) )  shape: (7, 2) ┌───────┬──────────────────┐ │ index ┆ mode │ │ --- ┆ --- │ │ u32 ┆ list[i64] │ ╞═══════╪══════════════════╡ │ 0 ┆ [3] │ │ 1 ┆ [3] │ │ 2 ┆ [4] │ │ 3 ┆ [1, 7, 4] │ │ 4 ┆ [1] │ │ 5 ┆ [1] │ │ 6 ┆ [10, 7, 9, 1, 4] │ └───────┴──────────────────┘  The commented out lines deal with discarding ties and getting rid of the list. shape: (7, 2) ┌───────┬──────┐ │ index ┆ mode │ │ --- ┆ --- │ │ u32 ┆ i64 │ ╞═══════╪══════╡ │ 0 ┆ 3 │ │ 1 ┆ 3 │ │ 2 ┆ 4 │ │ 3 ┆ null │ │ 4 ┆ 1 │ │ 5 ┆ 1 │ │ 6 ┆ null │ └───────┴──────┘
Question: import pandas as pd import seaborn as sn import matplotlib.pyplot as plt from datetime import datetime import numpy as np path = r'C:\Users\bossd\OneDrive\Документы\datarn.csv' df = pd.read_csv(path) path2 = r'C:\Users\bossd\OneDrive\Документы\pipirka.csv' df2 = pd.read_csv(path2) x = (df2.loc[df2['timestamp'].str.startswith('2015')]) y = df2['cnt'] plt.scatter(x,y) plt.show()  I wanted to build a scatterplot using dates that contain '2015' as x axis and 'cnt' parameter that means bicycles rent this day. But after running the code i get this error Cell In[47], line 14 12 x = (df2.loc[df2['timestamp'].str.startswith('2015')]) 13 y = df2['cnt'] ---> 14 plt.scatter(x,y) 15 plt.show() 17 display(df2) ... File ~\venv\lib\site-packages\matplotlib\category.py:214, in UnitData.update(self, data) 212 # check if convertible to number: 213 convertible = True --> 214 for val in OrderedDict.fromkeys(data): 215 # OrderedDict just iterates over unique values in data. 216 _api.check_isinstance((str, bytes), value=val) 217 if convertible: 218 # this will only be called so long as convertible is True. TypeError: unhashable type: 'numpy.ndarray'  The dataframe looks like this and containts timestamp as the day and cnt as the amount of bicycles rent this day data = {'timestamp': ['2015-01-04', '2015-01-05', '2015-01-06', '2015-01-07', '2015-01-08', '2016-12-27', '2016-12-28', '2016-12-29', '2016-12-30', '2016-12-31'], 'cnt': [9234, 20372, 20613, 21064, 15601, 10842, 12428, 14052, 11566, 11424]} df2 = pd.DataFrame(data)   timestamp cnt 0 2015-01-04 9234 1 2015-01-05 20372 2 2015-01-06 20613 3 2015-01-07 21064 4 2015-01-08 15601 5 2016-12-27 10842 6 2016-12-28 12428 7 2016-12-29 14052 8 2016-12-30 11566 9 2016-12-31 11424 

Answer:  The 'timestamp' column should first be converted to a datetime dtype with pd.to_datetime, otherwise the datetime x-ticks will not be correctly positioned and formatted.  The typical process should begin with cleaning the data, and then selecting.   x = (df2.loc[df2['timestamp'].str.startswith('2015')]) is the cause of the error, because it selects the entire dataframe, not a single column of the dataframe. And df2['cnt'] is not selected for the desired year. pandas.DataFrame.plot uses matplotlib as the default plotting backend, and should be used for plotting the dataframe.  # load the sample dataframe from the OP # convert timestamp to a datetime dtype df2.timestamp = pd.to_datetime(df2.timestamp) # select the data by year df_2015 = df2[df2.timestamp.dt.year.eq(2015)] # directly plot the dataframe, which uses matplotlib as the back end ax = df_2015.plot(x='timestamp', marker='.', ls='')    The x-ticks and labels will be formatted depending on the range of the data, which can be changed with the following answers  Changing the formatting of a datetime axis How to change the datetime tick label frequency   The x-axis limits can be set as shown in:  How to set xlim and xticks after plotting time-series data
Question: I have been using custom-defined DataclassProtocol to annotate the arg of function which takes dataclass type. It was something like this: import dataclasses from typing import Type class DataclassProtocol(Protocol): """Type annotation for dataclass type object.""" # https://stackoverflow.com/a/55240861/11501976 __dataclass_fields__: Dict def f(dcls: Type[DataclassProtocol]): return dataclasses.fields(dcls)  But recent mypy check fails with message: error: Argument 1 to "fields" has incompatible type "type[DataclassProtocol]"; expected "DataclassInstance | type[DataclassInstance]" [arg-type] It seems I should now annotate with this DataclassInstance, but I can't find out from where I can import this. Where can I find it?

Answer: You may import it from _typeshed: from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from _typeshed import DataclassInstance  Note that types from _typeshed do not exist at runtime. You may read more about them here:  _typeshed _typeshed.DataclassInstance
Question: Using Playwright and Python, how can I expect for count bigger or smaller than? For example, this code expect for count of 2. How do I achieve count >= 2 (Only bigger) expect(self.page.locator('MyLocator')).to_have_count(2, timeout=20 * 1000) 

Answer: This doesn't seem to be possible in the current Python Playwright API, but you could use wait_for_function as a workaround: page.wait_for_function("document.querySelectorAll('.foo').length > 2")  This is web-first and will wait for the predicate, but the error message once it throws won't be as clear as the expect failure. If the count is immediately available and you don't need to wait for the predicate to be true, assert is useful to mention as another possibility: assert page.locator(".foo").count() > 2  If you're using unittest, you can replace assert with, for example self.assertGreaterEqual(page.locator(".foo").count(), 2) self.assertGreater(page.locator(".foo").count(), 2) # or  Yet another workaround if you're dealing only with small numbers of elements: page.locator(".foo") expect(loc).not_to_have_count(0) expect(loc).not_to_have_count(1) expect(loc).not_to_have_count(2)  Here, we ensure the count is greater than 2 by process of elimination. It's impossible for count to be less than 0, so we need not include that. You could do this for less than as well, but not as easily, and using a reasonable assumption that there'll never be more than, say, 20 or 50 elements in any conceivable run: loc = page.locator(".foo") for i in range(2, 20): expect(loc).not_to_have_count(i)  This ensures the count is 0 or 1, or greater than some reasonably high upper-bound.
Question: I am running an app which needed uvicorn's asycio loop, by default it uses auto and some time it randomly assign it to uvloop whihc breaks the behavior. So I use the following command uvicorn myapp.server.api:app --loop asyncio --port 7474  This forces uvicorn to use asyncio loop. This works as expected. Now I am trying to move this changes to gunicorn and uvicorn as worker, but I am couldn't find a way to pass this loop to uvicorn. gunicorn myapp.server.api:app -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:7474  But this end up using default value i.e. auto and end up selecting loop type as uvloop. How can I force it to use asyncio worker. Help is appreciated.

Answer: The problem is gunicorn does not support passing options directly to uvicorn workers. So, basically, you can create a custom UvicornWorker class where you override the default loop policy. Here's an example: # myapp/server/custom_worker.py from uvicorn.workers import UvicornWorker class CustomUvicornWorker(UvicornWorker): CONFIG_KWARGS = {"loop": "asyncio"}  Then: gunicorn myapp.server.api:app -k myapp.server.custom_worker.CustomUvicornWorker --bind 0.0.0.0:7474
Question: In the pydantic v1 there was an option to add kwargs which would get passed to json.dumps via **dumps_kwargs. However, in pydantic v2 if you try to add extra kwargs to BaseModel.json() it fails with the error TypeError: `dumps_kwargs` keyword arguments are no longer supported. Here is example code with a workaround using dict()/model_dump(). This is good enough as long as the types are simple, but it won't work for the more complex data types that pydantic knows how to serialize. Is there a way to get sort_keys to work in pydantic v2 in general? import json from pydantic import BaseModel class JsonTest(BaseModel): b_field: int a_field: str obj = JsonTest(b_field=1, a_field="one") # this worked in pydantic v1 but raises a TypeError in v2 # print(obj.json(sort_keys=True) print(obj.model_dump_json()) # {"b_field":1,"a_field":"one"} # workaround for simple objects print(json.dumps(obj.model_dump(), sort_keys=True)) # {"a_field": "one", "b_field": 1} 

Answer: I'm not sure whether it is an elegant solution but you could leverage the fact that dictionaries (since python 3.7) preserve an order of elements: from typing import Any, Dict from pydantic import BaseModel, model_serializer class JsonTest(BaseModel): b_field: int c_field: int a_field: str @model_serializer(when_used='json') def sort_model(self) -> Dict[str, Any]: return dict(sorted(self.model_dump().items())) obj = JsonTest(b_field=1, a_field="one", c_field=0) print(obj.model_dump_json()) # {"a_field":"one","b_field":1,"c_field":0}
Question: I am trying to create a document term matrix using CountVectorizer to extract bigrams and trigrams from a corpus. from sklearn.feature_extraction.text import CountVectorizer lemmatized = dat_clean['lemmatized'] c_vec = CountVectorizer(ngram_range=(2,3), lowercase = False) ngrams = c_vec.fit_transform(lemmatized) count_values = ngrams.toarray().sum(axis=0) vocab = c_vec.vocabulary_ df_ngram = pd.DataFrame(sorted([(count_values[i],k) for k,i in vocab.items()], reverse=True) ).rename(columns={0: 'frequency', 1:'bigram/trigram'})  I keep getting the following error: MemoryError: Unable to allocate 7.89 TiB for an array with shape (84891, 12780210) and data type int64 While I have some experience with Python, I am pretty new to dealing with text data. I was wondering if there was a more memory efficient way to address this issue. I'm not sure if it is helpful to know, but the ngrams object is a scipy.sparse._csr.csr_matrix.

Answer: Solution: Here is one way to get the final table your looking for with frequency and bigram/trigram without generating the entire document term matrix. We can take the sum of a sparse matrix and use that to create a dataframe. This removes the need to create space in RAM for all of those missing values. # Here we create columns as vocabulary terms and a single row value as count of all terms. # We tranpose that to make it an index and a single column data = ngrams.sum(axis=0) keys = c_vec.vocabulary_.keys() df_ngram = pd.DataFrame(data, columns=keys).T # Get the count to its own column and rename all columns df_ngram.index.name = 'bigram/trigram' df_ngram.rename({0: 'count'}, inplace=True, axis=1) df_ngram.reset_index(inplace=True) # Calculate frequency of each term df_ngram['frequency'] = (df_ngram['count'] / df_ngram['count'].sum()) df_ngram.sort_values(by=['count'], ascending=False, inplace=True) df_ngram.head() # bigram/trigram count frequency # 1 (ngram here) (data) (data)  This could likely be simplified but it certainly does the job.
Question: I have a column that contain a list of dictionaries and I'm trying to write it to disk using parquet and reading it back into the same original object. However I'm not able to get the same exact object back. Here's the minimal code example to reproduce the issue: import pyarrow as pa from pyarrow import parquet import pandas as pd COLUMN1_SCHEMA = pa.list_(pa.struct([('Id', pa.string()), ('Age', pa.string())])) SCHEMA = pa.schema([pa.field("column1", COLUMN1_SCHEMA), ('column2', pa.int32())]) df = pd.DataFrame({ "column1": [[{"Id": "1"}, {"Age": "16"}], [{"Id": "2"},{"Age": "17"}]], "column2": [1, 2], }) table = pa.Table.from_pandas(df, schema=SCHEMA) parquet.write_table(table, "f.parquet") df = pa.parquet.read_table("f.parquet", schema=SCHEMA).to_pandas()  The problem is that the dataframe that is read back contains repeating dicts where each value is None (one at a time). Illustration below:  column1 column2 0 [{'Id': '1','Age': None}, {'Id': None, 'Age': '16'}] 1 1 [{'Id': '2','Age': None}, {'Id': None, 'Age': '17'}] 2  What I wanted was to get the original dataframe back:  column1 column2 0 [{'Id': '1'}, {'Age': '16'}] 1 1 [{'Id': '2'}, {'Age': '17'}] 2  Read documentation at pyarrow: https://arrow.apache.org/docs/python/index.html Read similar questions at stackoverflow but could not find an answer for this. Also could not find issues on the topic at Pyarrow's github.

Answer:  The problem is that the dataframe that is read back contains repeating dicts where each value is None (one at a time).  I'm not sure what your intention is. Do you want individual values to be a dictionary? If so I'd suggest sending the schema to this (no need for list_): COLUMN1_SCHEMA = pa.struct([('Id', pa.string()), ('Age', pa.string())])  And the values to this (no extra [] wrapper, everything in the same dict): [{"Id": "1", "Age": "16"}, {"Id": "2","Age": "17"}]  Which gives you     column1 column2     {'Id': '1', 'Age': '16'} 1   {'Id': '2', 'Age': '17'} 2
Question: I have two variables, and I am trying to use curve_fit in scipy optimize to fit the data. It looks alright, but the red line on the left portion does not fit so well to the data (green dots). How can I put some weights on the curve_fit() to shift the red line on left towards the blue line?  Here is the code: import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit from pandas import DataFrame x = [ 57, 83, 124, 141, 196, 223, 275, 302, 341, 714, 895, 1034, 1117, 1207, 1248, 1416, 1494, 1563, 1708, 1785, 1863, 2015, 2139, 2238, 2312, 2412, 2442, 2520, 2596, 2658, 2706, 2777, 2846, 2966, 3106, 3241, 3276, 3424, 3568, 3647, 3831, 3961, 4091, 4248, 4430, 4478, 4644, 4833, 5052, 6041 ] y = [ 70, 81, 87, 91, 96, 106, 109, 114, 120, 129, 144, 162, 168, 175, 181, 184, 190, 195, 205, 213, 216, 219, 224, 226, 231, 236, 239, 247, 255, 260, 264, 269, 282, 292, 297, 304, 308, 313, 319, 322, 327, 333, 338, 341, 345, 354, 362, 364, 374, 391 ] plt.scatter(x,y,color='green') def func(x, a, b): return a * np.power(x,b) popt, pcov = curve_fit(func, x, y) plt.plot(x, func(x, *popt), 'b-', label='fit: a=%5.3f, b=%5.3f' % tuple(popt)) popt2 = [12.6, 0.386] plt.plot(x, func(x, *popt2), 'r-', label='fit: a=%5.3f, b=%5.3f' % tuple(popt2)) plt.semilogx() 

Answer: You can use the parameter sigma in curve_fit. From the docs:  sigma: None or M-length sequence or MxM array, optional Determines the uncertainty in ydata. If we define residuals as r = ydata - f(xdata, *popt), then the interpretation of sigma depends on its number of dimensions: A 1-D sigma should contain values of standard deviations of errors in ydata. In this case, the optimized function is chisq = sum((r / sigma) ** 2). A 2-D sigma should contain the covariance matrix of errors in ydata. In this case, the optimized function is chisq = r.T @ inv(sigma) @ r.  So you can consider a 1-D sigma as inverse weights. To better fit a particular part of the curve, assign lower values of sigma to the specific points: plt.scatter(x,y,color='green') def func(x, a, b): return a * np.power(x,b) sigma = np.ones(len(x)) sigma[10:] *= 10 # set higher sigma for all data points other than the first 10 popt, pcov = curve_fit(func, x, y, sigma=sigma) plt.plot(x, func(x, *popt), 'b-', label='fit: a=%5.3f, b=%5.3f' % tuple(popt)) popt2 = [12.6, 0.386] plt.plot(x, func(x, *popt2), 'r-', label='fit: a=%5.3f, b=%5.3f' % tuple(popt2)) plt.semilogx()  Which results in:  You can play with sigma to get better results than the above.
Question: Consider I have a string formula which is written in this format: "func(a+b,c)", where func is a custom function, this string contains both infix(i.e. the +) and prefix(i.e. the func) representations, I'd like to convert it to a string with all prefix representations, "func(+(a,b), c)", how can I do that? Another example is "func1(a*(b+c),d)-func2(e,f)" to "-(func1(*(a, +(b,c)), d), func2(e,f))" More background: I want to build a parser, where the user would input the expressions in string format just as described above, normally a custom function would be written as a prefix expression, i.e. "func(a,b)", but due to the common convention, people would still write the +-*/ in an infix expression, i.e. "a+b". If an expression is given in all infix format, I can easily convert it to a tree object I predefined, but if an expression is mixed with both prefix and infix formats, I have no idea how to convert it to a tree object, thus asking how to convert the string to all infix formats. I have no experience with parsers, appreciate any initial guidance.

Answer: If the language you are parsing is that similar to Python, you can just use the Python parser as provided by the built-in ast module, and implement a visitor over the nodes that interest you, in order to build up the prefix expression. For example, you could try this: import ast def printc(*args): print(*args, end='') class PrefixPrinter(ast.NodeVisitor): def visit_BinOp(self, node): if type(node.op) == ast.Add: printc("+") if type(node.op) == ast.Sub: printc("-") if type(node.op) == ast.Mult: printc("*") if type(node.op) == ast.Div: printc("/") printc("(") self.visit(node.left) printc(",") self.visit(node.right) printc(")") def visit_Call(self, node): self.visit(node.func) printc("(") for index, arg in enumerate(node.args): self.visit(arg) if index < len(node.args) - 1: printc(", ") printc(")") def visit_Name(self, node): printc(node.id) first_example = "func(a+b,c)" second_example = "func1(a*(b+c),d)-func2(e,f)" printc(f"{first_example=} converts to ") PrefixPrinter().visit(ast.parse(first_example)) print() printc(f"{second_example=} converts to ") PrefixPrinter().visit(ast.parse(second_example)) print()  Execution: $ python3 to_prefix.py first_example='func(a+b,c)' converts to func(+(a,b), c) second_example='func1(a*(b+c),d)-func2(e,f)' converts to -(func1(*(a,+(b,c)), d),func2(e, f))
Question: I have a streamlit app where I want to get user input and use it later. However, I also want to clear the input field as soon as the user hits Enter. I looked online and it seems I need to pass a callback function to text_input but I can't make it work. I tried a couple different versions but neither works as I expect. import streamlit as st def clear_text(): st.session_state.my_text = "" # This version doesn't clear the text after hitting Enter. my_text = st.text_input("Enter text here", on_change=clear_text) # This version clears the field but doesn't save the input. my_text = st.text_input("Enter text here", on_change=clear_text, key='my_text') st.write(my_text)  The expectation is to save the input into my_text and clear the field afterwards. I looked at similar questions about clearing text input here and here but they're not relevant for my case because I want the input field to clear automatically while those cases talk about using a separate button. How do I make it work?

Answer: You can slightly adjust the solution provided by @MathCatsAnd : if "my_text" not in st.session_state: st.session_state.my_text = "" def submit(): st.session_state.my_text = st.session_state.widget st.session_state.widget = "" st.text_input("Enter text here", key="widget", on_change=submit) my_text = st.session_state.my_text st.write(my_text)  Output :
Question: The following code compiles and executes correctly: import numpy as np from numba import njit Particle = np.dtype([ ('position', 'f4'), ('velocity', 'f4')]) arr = np.zeros(2, dtype=Particle) @njit def f(x): x[0]['position'] = x[1]['position'] + x[1]['velocity'] * 0.2 + 1. f(arr)  However, making the datatype more highly dimensional causes this code to fail when compiling (but works without @njit): import numpy as np from numba import njit Particle = np.dtype([ ('position', 'f4', (2,)), ('velocity', 'f4', (2,)) ]) arr = np.zeros(2, dtype=Particle) @njit def f(x): x[0]['position'] = x[1]['position'] + x[1]['velocity'] * 0.2 + 1. f(arr)  With the following error: TypingError: Failed in nopython mode pipeline (step: nopython frontend) No implementation of function Function(<built-in function setitem>) found for signature: >>> setitem(Record(position[type=nestedarray(float32, (2,));offset=0],velocity[type=nestedarray(float32, (2,));offset=8];16;False), Literal[str](position), array(float64, 1d, C)) There are 16 candidate implementations: - Of which 16 did not match due to: Overload of function 'setitem': File: <numerous>: Line N/A. With argument(s): '(Record(position[type=nestedarray(float32, (2,));offset=0],velocity[type=nestedarray(float32, (2,));offset=8];16;False), unicode_type, array(float64, 1d, C))': No match. During: typing of staticsetitem at /tmp/ipykernel_21235/2952285515.py (13) File "../../../../tmp/ipykernel_21235/2952285515.py", line 13: <source missing, REPL/exec in use?>  Any thoughts on how to remedy the later one? I would like to use more highly dimensionalized datatypes.

Answer: You can try to use [:] to set values of the array: import numpy as np from numba import njit Particle = np.dtype([("position", "f4", (2,)), ("velocity", "f4", (2,))]) arr = np.zeros(2, dtype=Particle) @njit def f(x): pos_0 = x[0]["position"] pos_0[:] = x[1]["position"] + x[1]["velocity"] * 0.2 + 1.0 #x[0]["position"][:] = ... works too f(arr) print(arr)  Prints: [([1., 1.], [0., 0.]) ([0., 0.], [0., 0.])]
Question: I'm trying to match only the second valid ip address in a string with a range of ip addresses. Sometimes it's written without a space between addresses and something it has one or more spaces. Also sometimes the ip isn't valid so it shouldn't match. test = ''' 1.0.0.0-1.0.0.240 2.0.0.0 - 1.0.0.241 3.0.0.0 -1.0.0.242 4.0.0.0- 1.0.0.243 5.0.0.0 - 1.0.0.244 6.0.0.0 - 1.0.0.245 7.0.0.0 - 1.0.0.2456 #NOT VALID SO DONT MATCH ''' pattern = r"(?<=-\s))\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" r = re.compile(pattern, re.DOTALL) print(r.findall(test))  My try only catches: 1.0.0.241 and 1.0.0.243

Answer: Change regex pattern to the following: pattern = r"(?<=[-\s])((?:\d{1,3}\.){3}\d{1,3})$" r = re.compile(pattern, re.M) print(r.findall(test))    (?<=[-\s]) - lookbehind assertion to match either - or \s as a boundary before IP address (which is enough in your case) (?:\d{1,3}\.){3} - matches the 3 first octets each followed by . of IP address $ - matches the end of the string in a multi-lined text (recognized by re.M)   ['1.0.0.240', '1.0.0.241', '1.0.0.242', '1.0.0.243', '1.0.0.244', '1.0.0.245']