2017-01-05 2 views
1

У меня есть программа, которая сканирует Google для ссылок, он проверяет, сколько ссылок вы нашли, а затем пытается найти успех прямо для вашего поиска:Как использовать диапазон для ключей dict?

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 
} 

Однако очевидно, что это не работает, потому что списки не являются hashable объекты:

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' 

Is есть способ, которым я мог бы использовать диапазон для ключа dict, чтобы избавить себя от необходимости делать ключ от 1   -   100?

+0

Сделайте их кортежи. кортежи хешируются. 'tuple (range (1, 10))' –

+1

Вы не хотели бы использовать списки здесь, нет, потому что они содержат * все целые числа в диапазоне *. Вместо этого используйте объекты 'xrange()', они хешируются и сохраняют только начальные и конечные значения. –

+1

кажется, что вы округляете до ближайшего «10-го», почему бы просто не сделать это вместо поиска – MooingRawr

ответ

2

range() в Python 2 - это просто функция, которая возвращает список целых чисел, сама по себе не является типом объекта. И вы не хотели бы использовать списки здесь, нет, потому что они содержат все целые числа в диапазоне.

Вместо этого вы можете использовать xrange() objects, они являются хешируемыми и сохраняют только начальные и конечные значения. Однако, если вы не планируете использовать другиеxrange() объекты для проверки этих ключей, словарь с такими ключами не очень полезен, вам придется перебирать словарь, чтобы проверить свой курс по каждому объекту xrange вручную.

Ваш словарь скорости успеха можно было бы просто заменить математикой; просто округлить свои номера до ближайшего числа, кратного 10 (просто используя пол деление):

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

ли испытание, если что полученное значение находится в пределах от 10 до 100:

10 <= success_rate <= 100 
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

Смежные вопросы