My list =[ ' 14,200 new items ' , '15,200 new items '] I tried for loop with isdigit to extract number But output was blank list .
I think you need to process each item in the list as a split string on whitespace.
a = ['1 2 3', '4 5 6', 'invalid']
numbers = []
for item in a:
for subitem in item.split():
if(subitem.isdigit()):
numbers.append(subitem)
print(numbers)
['1', '2', '3', '4', '5', '6']
Or in a neat and tidy comprehension:
[item for subitem in a for item in subitem.split() if item.isdigit()]
That should do for your particular case since you include a string within list. Therefore you need to flatten it:
new_list = [int(item) for sublist in a for item in sublist if item.isdigit()]
Python Extracting numbers and adding them from a list - Stack Overflow
Extract numbers from a string list - python - Stack Overflow
python - Extract numbers from list of lists - Stack Overflow
extracting numbers from list of strings with python - Stack Overflow
Videos
Using re.search and a regex pattern, you can extract the integer value from the string.
>>> import re
>>>
>>> re.search(r'\d+', data[9])
<_sre.SRE_Match object; span=(16, 19), match='102'>
>>> re.search(r'\d+', data[9]).group(0)
'102'
>>> speed = int(re.search(r'\d+', data[9]).group(0))
>>> speed
102
Here, re.search(r'\d+', data[9]) will return a match if data[9] has any decimal characters. Then retrieving this decimal characters using .group(0) and finally convert them to integer, using int() built-in method
>>> int(data[9][-4:-1])+1
103
Use iterable[start:end] to get a subset of them.
Another thing you can do is, if you want to get a single integer from a string, is something along the lines of (python2.x):
s = "test123\n"
x = int(filter(lambda x: x.isdigit(), s))
In Python3, filter returns a filter object which is an iterable. You can turn it into a list and join them for the same functional result.
s = "test123\n"
x = int(''.join(list(filter(lambda x: x.isdigit(), s))))
Note that this does not take into account separated numbers. For example, s = "123test456" will return 123456. If you want them separated, you will need to use something a bit more clever.
>>> s = "\n123test456\n"
>>> nums = map(int, ''.join([x if x.isdigit() else ' ' for x in s]).split())
>>> print(nums)
[123, 456]
Again, in python3, map returns a map object, so you just have to convert it to a list.
>>> s = "\n123test456\n"
>>> nums = list(map(int, ''.join([x if x.isdigit() else ' ' for x in s]).split()))
>>> print(nums)
[123, 456]
>>> import re
>>> elements = [' 86 miles\n', ' 43 miles\n', ' MV\n', ' 0.0 miles\n', ' 43 miles\n', ' 15.0 m iles\n', ' 0.0 miles\n', ' 0.0 miles\n', ' 0.0 miles \n', ' 86 miles\n', ' .7 miles', ' 5. miles']
>>> _re_digits = re.compile(r"(-?(?:(?:\d+(?:\.\d*)?)|(?:\.\d+)))")
>>> digits = []
>>> for element in elements:
digits += [ float(n) for n in _re_digits.findall(element)]
>>> digits
[86.0, 43.0, 0.0, 43.0, 15.0, 0.0, 0.0, 0.0, 86.0, 0.7, 5.0]
>>> sum(digits)
278.7
Assuming you want the numbers as floats:
miles = [' 86 miles\n', ' 43 miles\n', ' MV\n', ' 0.0 miles\n', ' 43 miles\n', ' 15.0 miles\n', ' 0.0 miles\n', ' 0.0 miles\n', ' 0.0 miles \n', ' 86 miles\n']
total = 0.0
for s in miles:
for t in s.split():
try:
total += float(t)
except ValueError:
pass
x = [ [100] , [500] , [300] ]
y = [ i[0] for i in x]
#or
from itertools import chain
y = list(chain.from_iterable(x))
From this question:
l=[[100], [500], [300]]
result=[item for sublist in l for item in sublist]
From wikibooks:
def flatten(seq, list = None):
"""flatten(seq, list = None) -> list
Return a flat version of the iterator `seq` appended to `list`
"""
if list == None:
list = []
try: # Can `seq` be iterated over?
for item in seq: # If so then iterate over `seq`
flatten(item, list) # and make the same check on each item.
except TypeError: # If seq isn't iterable
list.append(seq) # append it to the new list.
return list
Google is your friend ...
The problem is with your regex. You need to remove the $ anchor, which will fail to match a number if anything (e.g. the % character) is following the expected characters, namely [0-9,.]. The rest of the rest of the code can be simplified a bit, too:
import re
from collections import defaultdict
my_list=[['word:', 'house', 'garden', '0,2%'],
['word:', 'house', 'garden', '0,2%'],
['house', 'garden', '0,2%'],
['house', 'garden', '0,2%'],
['garden', '0,2%', '0,125%'],
['house', '0,2%', '?????'],
['house', 'garden', '0,02%'],
['house', 'garden', '0,02%'],
['garden', '0,02%'],
['house', 'garden', '0,2%'],
['garden', '0,2%'],
['house', '0,2'],
['house', '0,2', '%'],
['house', 'garden', 'kids', '0,2%'],
['house', 'garden', 'kids', '0,2%'],
['house', '0,2%', 'boy'],
['house', '0,12%'],
['house', '4%.'],
['house', '4%.', '4.'],
['house', '0,2%".']]
result = defaultdict(list)
keywords = ['house', 'garden']
for l in my_list:
numbers = [v for v in l if re.match(r'[0-9,.]+', v)]
for v in l:
if v in keywords:
result[v].extend(numbers)
print(result)
Prints:
defaultdict(<class 'list'>, {'house': ['0,2%', '0,2%', '0,2%', '0,2%', '0,2%', '0,02%', '0,02%', '0,2%', '0,2', '0,2', '0,2%', '0,2%', '0,2%', '0,12%', '4%.', '4%.', '4.', '0,2%".'], 'garden': ['0,2%', '0,2%', '0,2%', '0,2%', '0,2%', '0,125%', '0,02%', '0,02%', '0,02%', '0,2%', '0,2%', '0,2%', '0,2%']})
Here is what you can do:
my_list=[['word:', 'house', 'garden', '0,2%'],
['word:', 'house', 'garden', '0,2%'],
['house', 'garden', '0,2%'],
['house', 'garden', '0,2%'],
['garden', '0,2%', '0,125%'],
['house', '0,2%', '?????'],
['house', 'garden', '0,02%'],
['house', 'garden', '0,02%'],
['garden', '0,02%'],
['house', 'garden', '0,2%'],
['garden', '0,2%'],
['house', '0,2'],
['house', '0,2', '%'],
['house', 'garden', 'kids', '0,2%'],
['house', 'garden', 'kids', '0,2%'],
['house', '0,2%', 'boy'],
['house', '0,12%'],
['house', '4%.'],
['house', '4%.', '4.'],
['house', '0,2%โ.']]
my_dict = { 'garden':[], 'house':[]}
for lst in my_list:
for s in lst:
if any([n in s for n in '1234567890']):
if 'house' in lst:
my_dict['house'].append(s.replace('%',''))
if 'garden' in lst:
my_dict['garden'].append(s.replace('%',''))
print(my_dict)
Output:
{'garden': ['0,2', '0,2', '0,2', '0,2', '0,2', '0,125', '0,02', '0,02', '0,02', '0,2', '0,2', '0,2', '0,2'], 'house': ['0,2', '0,2', '0,2', '0,2', '0,2', '0,02', '0,02', '0,2', '0,2', '0,2', '0,2', '0,2', '0,2', '0,12', '4.', '4.', '4.', '0,2โ.']}
You can use id\s(\d{7}) regular expression.
Iterate over items in a list and join the results of findall() call by ;:
import re
lst1 = [
'(Tower 3rd floor window corner_ : option 3_floor cut out_large : GA - floors : : model lines : id 3999595(tower 4rd floor window corner : option 3_floor: : whatever else is in iit " new floor : id 3999999)',
'(Tower 3rd floor window corner_ : option 3_floor cut out_large : GA - floors : : model lines : id 3998895(tower 4rd floor window corner : option 3_floor: : id 5555456 whatever else is in iit " new floor : id 3998899)'
]
pattern = re.compile(r'id\s(\d{7})')
print ["; ".join(pattern.findall(item)) for item in lst1]
prints:
['3999595; 3999999', '3998895; 5555456; 3998899']
Based on @alecxe solution you can also do it without any imports.
If your id numbers are always after id and have a fixed (7) number of digits I would probably just use .split('id ') to separate it and get the 7 digits from the second block onwards.
You can put them together in the desired format by using '; '.join()
Putting everything together:
pattern = ['; '.join([value[:7] for value in valueList.split('id ')[1:]]) for valueList in lst1]
Which prints out:
['3999595; 3999999', '3998895; 5555456; 3998899']