【问题标题】:Sort values for both str and int by ranking appearance in a string通过对字符串中的外观进行排名,对 str 和 int 的值进行排序
【发布时间】:2021-02-08 02:50:43
【问题描述】:

我必须对字符串中的关键字和值进行排序。

这是我的尝试:

import re
phrase='$1000 is the price of the car, it is 10 years old. And this sandwish cost me 10.34£'
list1 = (re.findall('\d*\.?\d+', phrase)) #this is to make a list that find all the ints in my phrase and sort them (1000, 10, 10.34)

list2= ['car', 'year', 'sandwish'] #this is to make a list of all the keywords in the phrase I need to find.

joinedlist = list1 + list2 #This is the combination of the 2 lists int and str that are in my sentence (the key elements)

filter1 = (sorted(joinedlist, key=phrase.find)) #This is to find all the key elements in my phrase and sort them by order of appearance.

print(filter1)

不幸的是,在某些情况下,因为“sorted”函数通过词法排序工作,积分会以错误的顺序打印。这意味着在某些情况下,像这种情况,输出将是:

['1000', '10', 'car', 'year', 'sandwich', '10.34']

代替:

['1000', 'car', '10', 'year', 'sandwich', '10.34']

因为汽车在初始短语中出现在 10 之前。

【问题讨论】:

  • 你得到你看到的输出的原因是100010出现在phrase的同一个地方,所以在filter1中是第一个。

标签: python string list sorting integer


【解决方案1】:

问题在于101000 在 Python 的默认字符串查找中具有相同的值。两者都在字符串的开头,因为101000 的子字符串。

可以实现对phrase 的正则表达式查找,以通过使用\b 字边界来实现您尝试的方法,以便10 仅匹配字符串中的10

def finder(s):
    if m:=re.search(rf'\b{s}\b', phrase):
        return m.span()[0]
    elif m:=re.search(rf'\b{s}', phrase):
        return m.span()[0]
    return -1   

测试一下:

>>> sorted(joinedlist, key=finder)
['1000', 'car', '10', 'year', 'sandwish', '10.34']

不过,如果您将phrase 转换为您的关键字查找列表会更容易。您需要将year 作为关键字与phrase 中的years 进行一些处理;您可以使用正则表达式 r'\d+\.\d+|\w+' 作为正则表达式来查找单词,然后使用 str.startswith() 来测试它是否足够接近:

pl=re.findall(r'\d+\.\d+|\w+', phrase)

def finder2(s):
    try:                    # first try an exact match
        return pl.index(s)
    except ValueError:
        pass                # not found; now try .startswith()
    try:    
        return next(i for i,w in enumerate(pl) if w.startswith(s))  
    except StopIteration:
        return -1   

>>> sorted(joinedlist, key=finder2)
['1000', 'car', '10', 'year', 'sandwish', '10.34']

【讨论】:

    【解决方案2】:

    词法排序与它无关,因为你的排序key是原词组中的位置;所有排序均由数值完成(find 返回的索引)。 '10' 出现“乱序”的原因是 phrase.find 返回它的第一次出现,它在字符串的 1000 部分内!

    与其将句子分成两个列表,然后尝试用sort 重新组合它们,为什么不只使用一个正则表达式来选择您想要保留的不同类型的东西呢?这样你根本不需要重新排序:

    >>> re.findall('\d*\.?\d+|car|year|sandwish', phrase)
    ['1000', 'car', '10', 'year', 'sandwish', '10.34']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-05
      • 2015-07-27
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2017-11-12
      相关资源
      最近更新 更多