从列表中提取整数

时间:2017-07-07 06:20:30

标签: python python-2.7 nlp

我有一个这样的清单:

fmt_string="I am a smoker male of 25 years who wants a policy for 30 
yrs with a sum assured amount of 1000000 rupees"

从上面的列表中我删除了停用词然后得到了这个 现在我有一个列表如下:

['smoker', 'male', '25', 'years', 'wants', 'policy', '30', 'yrs', 
'sum', 'assured', 'amount', '1000000', 'rupees']

从这个列表中我想提取25,30和1000000,但代码应该是25之前或之后的年份。 30可以是在政策之后,1000000可以在任何位置

最后输出应该是:

'1000000 30 25 male smoker'

我只想要一个健壮的代码,无论我在哪里找到这些值,我都会返回一个这样的列表。

2 个答案:

答案 0 :(得分:0)

这应该有用

import re
# Variation in places of the numbers in strings:
str1 = "I am a smoker male of 25 years who wants a policy for 30  yrs with a sum assured amount of 1000000 rupees"
str2 = "I am a smoker male of 25 years who wants a for 30 policy  yrs with a sum assured amount of 1000000 rupees"
str3 = "I am a smoker male of years 25 who wants a for 30 policy yrs with a sum assured amount of 1000000 rupees"
str4 = "I am a smoker male of 25 years who wants a for 30 policy yrs with a sum assured amount of 1000000 rupees"

regex = r".*?(((\d{2})\s?years)|(years\s?(\d{2}))).*(policy.*?(\d{2})|(\d{2}).*?policy).*(\d{7}).*$"
replacements = r"\9 \7 \8 \3 \5"

res_str1 = re.sub(regex, replacements, str1)
res_str2 = re.sub(regex, replacements, str2)
res_str3 = re.sub(regex, replacements, str3)
res_str4 = re.sub(regex, replacements, str4)


def clean_spaces(string):
    return re.sub(r"\s{1,2}", ' ', string)


print(clean_spaces(res_str1))
print(clean_spaces(res_str2))
print(clean_spaces(res_str3))
print(clean_spaces(res_str4))

输出:

1000000 30 25 
1000000 30 25 
1000000 30 25
1000000 30 25

<强>更新

上面的正则表达式有一些错误。当我试图改进它时,我注意到它是低效和丑陋的,因为它每次都会解析每个单个字符。如果我们坚持你原来解析单词的方法,我们可以做得更好。所以我的新解决方案是:

# Algorithm
# for each_word in the_list:
#     maintain a pre_list of terms that come before a number
#     if each_word is number:
#         if there is any element of desired_terms_list exists in pre_list:
#             pair the number & the desired_term and insert into the_dictionary
#             remove this desired_term from desired_terms_list
#             reset the pre_list
#         else:
#             put the number in number_at_hand
#     else:
#         if no number_at_hand:
#             add the current word into pre_list
#         else:
#             if the current_word an element of desired_terms_list:
#                 pair the number & the desired_term and insert into the_dictionary
#                 remove this desired_term from desired_terms_list
#                 reset number_at_hand

代码:

from pprint import pprint


class Extractor:
    def __init__(self, search_terms, string):
        self.pre_list = list()
        self.list = string.split()
        self.terms_to_look_for = search_terms
        self.dictionary = {}

    @staticmethod
    def is_number(string):
        try:
            int(string)
            return True
        except ValueError:
            return False

    def check_pre_list(self):
        for term in self.terms_to_look_for:
            if term in self.pre_list:
                return term
            else:
                return None

    def extract(self):
        number_at_hand = str()
        for word in self.list:
            if Extractor.is_number(word):
                check_result = self.check_pre_list()
                if check_result is not None:
                    self.dictionary[check_result] = word
                    self.terms_to_look_for.remove(check_result)
                    self.pre_list = list()
                else:
                    number_at_hand = word
            else:
                if number_at_hand == '':
                    self.pre_list.append(word)
                else:
                    if word in self.terms_to_look_for:
                        self.dictionary[word] = number_at_hand
                        self.terms_to_look_for.remove(word)
                        number_at_hand = str()
        return self.dictionary

用法:

ex1 = Extractor(['years', 'policy', 'amount'],
                'I am a smoker male of 25 years who wants a policy for 30 yrs with a sum assured amount of 1000000 rupees')
ex2 = Extractor(['years', 'policy', 'amount'],
                'I am a smoker male of 25 years who wants a for 30 yrs policy with a sum assured amount of 1000000 rupees')
ex3 = Extractor(['years', 'policy', 'amount'],
                'I am a smoker male of years 25 who wants a policy for 30 yrs with a sum assured amount of 1000000 rupees')
ex4 = Extractor(['years', 'policy', 'amount'],
                'I am a smoker male of years 25 who wants a for 30 yrs policy with a sum assured amount of 1000000 rupees')
pprint(ex1.extract())
pprint(ex2.extract())
pprint(ex3.extract())
pprint(ex4.extract())

输出:

{'amount': '1000000', 'policy': '30', 'years': '25'}
{'amount': '1000000', 'policy': '30', 'years': '25'}
{'amount': '1000000', 'policy': '30', 'years': '25'}
{'amount': '1000000', 'policy': '30', 'years': '25'}

我希望现在能有更好的表现。

答案 1 :(得分:-1)

使用re在列表中findall出现,join用逗号split来列出并将reverse()应用于列表,然后join ' '再次

您的数据:

li = ['smoker', 'male', '25', 'years', 'wants', 'policy', '30', 'yrs', 'sum', 'assured', 'amount', '1000000', 'rupees']

temp=",".join([l for l in li if re.findall('1000000|30|25|male|smoker',l)]).split(",")

temp.reverse()
temp = " ".join(temp)

输出:

'1000000 30 25 male smoker'

希望这个答案有用。