作为python lambdas中的一个练习(只是这样我可以学习如何更好地使用它们)我给自己做了一个赋值,根据除了它们的自然字符串顺序之外的东西来排序一些字符串。
我为版本号字符串删除了apache,然后想出了一个lambda来根据我用regexes提取的数字对它们进行排序。它有效,但我认为可能更好,我只是不知道如何改进它,因此它更健壮。
from lxml import html
import requests
import re
# Send GET request to page and parse it into a list of html links
jmeter_archive_url='https://archive.apache.org/dist/jmeter/binaries/'
jmeter_archive_get=requests.get(url=jmeter_archive_url)
page_tree=html.fromstring(jmeter_archive_get.text)
list_of_links=page_tree.xpath('//a[@href]/text()')
# Filter out all the non-md5s. There are a lot of links, and ultimately
# it's more data than needed for his exercise
jmeter_md5_list=list(filter(lambda x: x.endswith('.tgz.md5'), list_of_links))
# Here's where the 'magic' happens. We use two different regexes to rip the first
# and then the second number out of the string and turn them into integers. We
# then return them in the order we grabbed them, allowing us to tie break.
jmeter_md5_list.sort(key=lambda val: (int(re.search('(\d+)\.\d+', val).group(1)), int(re.search('\d+\.(\d+)', val).group(1))))
print(jmeter_md5_list)
这确实有所需效果,输出为:
['jakarta-jmeter-2.5.1.tgz.md5', 'apache-jmeter-2.6.tgz.md5', 'apache-jmeter-2.7.tgz.md5', 'apache-jmeter-2.8.tgz.md5', 'apache-jmeter-2.9.tgz.md5', 'apache-jmeter-2.10.tgz.md5', 'apache-jmeter-2.11.tgz.md5', 'apache-jmeter-2.12.tgz.md5', 'apache-jmeter-2.13.tgz.md5']
因此我们可以看到字符串被分类为有意义的顺序。最低版本第一版和最高版本。我在解决方案中看到的直接问题是双重的。
所以它有效,但必须有更好的方法。我怎样才能改善这个?
答案 0 :(得分:1)
这不是一个完整的答案,但它会让你走得很远。
键函数的返回值可以是元组,元组自然排序。您希望键功能的输出为:
((2, 5, 1), 'jakarta-jmeter')
((2, 6), 'apache-jmeter')
etc.
请注意,无论如何,这对于lambda来说都是一个糟糕的用例。
答案 1 :(得分:0)
最初,我想出了这个:
jmeter_md5_list.sort(key=lambda val: list(map(int, re.compile('(\d+(?!$))').findall(val))))
然而,根据Ignacio Vazquez-Abrams的回答,我做了以下修改。
def sortable_key_from_string(value):
version_tuple = tuple(map(int, re.compile('(\d+(?!$))').findall(value)))
match = re.match('^(\D+)', value)
version_name = ''
if match:
version_name = match.group(1)
return (version_tuple, version_name)
和此:
jmeter_md5_list.sort(key = lambda val: sortable_key_from_string(val))