如何使用dict键的范围?

时间:2017-01-05 17:32:15

标签: python python-2.7 dictionary key

我有一个程序可以扫描谷歌搜索链接,它会验证您找到的链接数量,然后尝试找到适合您搜索的成功:

def check_urls_for_queries(self):
    """ The returned URLS will be run through a query regex to see if
        they have a query parameter.
          http://google.com <- False
          http://example.com/php?id=2 <- True
    """
    filename = settings.create_random_filename()
    print("File being saved to: {}".format(filename))
    with open("{}\\{}.txt".format(settings.DORK_SCAN_RESULTS_PATH, filename),
              "a+") as results:
        for url in self.connect_to_search_engine():
            match = settings.QUERY_REGEX.match(url) # Match by regex for anything
                                                    # that has a ?=<PARAM> in it
            if match:
                results.write(url + "\n")
    amount_of_urls = len(open(settings.DORK_SCAN_RESULTS_PATH + "\\" + filename
                              + ".txt", 'r').readlines())
    return("\nFound a total of {} usable links with query (GET) parameters, urls"
           " have been saved to {}\\{}.txt. This Dork has a success rate of {}%".
           format(amount_of_urls, settings.DORK_SCAN_RESULTS_PATH, filename,
                  self.success_rate[amount_of_urls]
                    if amount_of_urls in self.success_rate.keys() else
                  'Unknown success rate'))

我想要做的是使用每个dict键的范围创建成功率:

success_rate = {
    range(1, 10): 10, range(11, 20): 20, range(21, 30): 30,
    range(31, 40): 40, range(41, 50): 50, range(51, 60): 60,
    range(61, 70): 70, range(71, 80): 80, range(81, 90): 90,
    range(91, 100): 100
}

但显然这不起作用,因为列表不是可清除的对象:

Traceback (most recent call last):
  File "tool.py", line 2, in <module>
    from lib.core import BANNER
  File "C:\Users\Documents\bin\python\pybelt\lib\core\__init__.py", line 1, in <module>
    from dork_check import DorkScanner
  File "C:\Users\Documents\bin\python\pybelt\lib\core\dork_check\__init__.py", line 1, in <module>
    from dorks import DorkScanner
  File "C:\Users\\Documents\bin\python\pybelt\lib\core\dork_check\dorks.py", line 6, in <module>
    class DorkScanner(object):
  File "C:\Users\Documents\bin\python\pybelt\lib\core\dork_check\dorks.py", line 11, in DorkScanner
    range(1, 10): 10, range(11, 20): 20, range(21, 30): 30,
TypeError: unhashable type: 'list'

有没有办法可以使用dict键的范围来保存自己不必从1 - 100创建一个键?

2 个答案:

答案 0 :(得分:2)

Python 2中的

range()只是一个返回整数列表的函数,它本身不是一种对象。你不想在这里使用列表,不,因为它们包含范围内的所有整数

您可以使用xrange() objects代替它们,它们是可清除的,只存储起始值和结束值。但是,除非您计划使用其他 xrange()对象来测试这些键,否则带有此类键的字典不是很有用,您必须循环遍历字典以测试您的手动对每个xrange对象进行评分。

您的成功率字典可以更简单地被数学取代;只是将你的数字四舍五入到最接近的10的倍数(简单地使用地板划分):

success_rate = ((amount_of_urls // 10) + 1) * 10

测试结果值是否介于10和100之间:

10 <= success_rate <= 100

答案 1 :(得分:1)

RangeKeyDict类可以处理这样的情况,这种情况更通用且易于使用。如需使用,请检查__main __

中的代码

使用以下方式安装它:

pip install range-key-dict

用法:

from range_key_dict import RangeKeyDict

if __name__ == '__main__':
    range_key_dict = RangeKeyDict({
        (0, 100): 'A',
        (100, 200): 'B',
        (200, 300): 'C',
    })

    # test normal case
    assert range_key_dict[70] == 'A'
    assert range_key_dict[170] == 'B'
    assert range_key_dict[270] == 'C'

    # test case when the number is float
    assert range_key_dict[70.5] == 'A'

    # test case not in the range, with default value
    assert range_key_dict.get(1000, 'D') == 'D'

https://github.com/albertmenglongli/range-key-dict

参考:请在这篇文章中查看答案:Range as dictionary key in Python