2010-10-29 4 views
1

Работа с несколькими списками, итерация по каждому из них. Вот фрагмент кода:Как перейти к следующему элементу во вложенном списке? Python

self.links = [] 
self.iter=iter(self.links) 
for tgt in self.links: 
    for link in self.mal_list: 
     print(link) 
     if tgt == link: 
      print("Found Suspicious Link: {0}".format(tgt)) 
      self.count += 1 

     else: 
      self.count += 1 
      self.crawl(self.iter.next()) 

Его переход на следующий элемент в списке ссылок, просто отлично. Для списка подписи вредоносных программ я попытался использовать аналогичный элемент iter, но я не совсем уверен, что это даже лучший способ, и если бы это было поместить его в мой код, чтобы каждая ссылка, которая была скрыта из списка, сравнивалась с каждый элемент в списке вредоносных программ. Перед циклом открывается следующий элемент в списке ссылок. Какие-либо предложения?

ответ

1

Существенный способ, которым вы это выполняете, хорошо, но он будет медленным.

Попробуйте вместо этого:

for tgt in links: 
     if tgt in mal_links: 
      # you know that it's a bad link 
     else: 
      crawl(tgt) 

Я не понимаю, почему вы держите два итератора, идущие по списку. Это приведет к ошибке, потому что вы не вызываете next на self.iter в случае обнаружения вредоносной ссылки. В следующий раз, когда tgt не является плохой ссылкой, когда вы вызываете next, он будет продвигаться к ранее обнаруженной плохой ссылке, и вы сканируете это. Есть ли какая-то причина, по которой вы чувствуете необходимость перешагнуть через две копии итератора вместо одного?

Кроме того, ваш первоначальный код будет сканировать страницу один раз за каждый раз, когда он не определен как равный данной ссылке вредоносного ПО. Это может привести к некоторым сердитым веб-мастерам в зависимости от того, насколько велик ваш список.

+0

@aaronasterling: +1 Хорошо поймать эту ошибку !! – pyfunc

+0

Ну, я сделал self.iter, потому что при вызове crawl (tgt) он просто продолжал сканировать первый элемент в списке ссылок снова и снова. Я понимаю, что у вас есть здесь, чтобы удалить второй цикл, подумав о том, что он делает, это имеет смысл, но теперь я остаюсь с оригинальной проблемой, потому что это не продвигающие элементы. это лучший способ сделать это и обеспечить, чтобы я вызывал .next() в обоих блоках операторов if-else? – Stev0

+0

@ Stev0: Это будет ошибкой в ​​вашем crawl(); вам, вероятно, будет лучше исправить это там. –

2

Не уверен, что вы пытаетесь спросить, но вы можете упростить свой код. Хотя это не обязательно.

self.links = [] 
self.non_malware_link = [link for link in self.links if link not in self.mal_list] 
results = map(self.crawl, self.non_malware_link) 

О некоторых вопросах с кодом:

  1. self.count точно так же, как LEN (self.links)

Помимо значения self.count, каждая вещь иначе похоже, что он делает то, что нужно.

+0

Я предполагаю, что он будет использовать self.count, чтобы сообщить пользователю о текущем ходе сканирования? –

+0

@Lie Ryan: Спасибо, хорошо! – pyfunc

+0

@ Stev0: @ Ли Райан: Кто-то проголосовал за меня. Мой ответ остается здесь для справки, но я нахожу ответ Ли Райана столь же изящным, как и использование наборов, устраняет ненужное дублирование сравнения. Я голосую за его ответ. Пожалуйста, смотрите. Предложение aaronasterling также имеет большой смысл. – pyfunc

1

Поиск элемент внутри списка медленна, если это то, что вы пытаетесь сделать, то использовать dict или в set вместо list для self.mal_list:

mal_list = set(self.mal_list) 
for tgt in self.links: 
    if tgt in mal_list: 
     print("Found Suspicious Link: {0}".format(tgt)) 
     self.count += 1 
    else: 
     self.count += 1 
     self.crawl(self.iter.next()) 

или, если вы можете имеют self.links как установлено:

mal_list = set(self.mal_list) 
links = set(self.links) 
detected = links.intersection(mal_list) 
for malware in detected: 
    print("Found Suspicious Link: {0}".format(tgt)) 
    self.count += 1 
+0

Хорошо подумал об использовании наборов, но, перейдя через две версии 'links', вы перенесли ошибку из исходного кода OP. – aaronasterling

+0

Спасибо за информацию о наборах, что я могу сделать, чтобы ускорить ее. – Stev0