删除一个集合中的一个项目包含另一个集合项目的项目

时间:2019-02-18 21:55:48

标签: python

我的整个应用程序有点sitemap-Scraper,我向它提供了根链接,从这里它会扫描该站点以查找更多链接,然后也刮这些站点以获取更多链接,有点像sitemap-gen更详细。 更大的前景是,有些网站包含 youtube,facebook,google等。这些网站可能会导致永恒,并将我的应用置入边缘链,因此,我决定为它提供 blocker ,以便我们删除那些更大的网站 < / p>

我有一个名为blocked_sites.txt的文件,其中有:

facebook
youtube

我有一个set,其中有:

'facebook.com', 'youtube.com', 'gold'

所以,我想做的是:

  1. 比较两个列表
  2. 检查是否 urls 项目包含 blocked_sites 项目
  3. 如果该项目包含阻止的项目,则删除该项目

我完成了第1点和第2点,但是第三个是一个陷阱,这是我先发制人尝试过的事情:

 # For every url in urls
 for url in urls:
   # For every blocker inside blocked
   for blocker in blocked:      
      # If URL contains BLOCKER
      if blocker in url:
         # Remove THAT URL
         urls.remove(url)
         print('removed: ' + url)
print(urls)

问题是我无法同时遍历一个集合时真正修改它。那我有什么选择呢?

这里是我的想法:

  1. 获取{strong> DOESNT 包含阻止程序的URL并将其复制到另一组 -这似乎有点笨重,我的意思是,然后我们将不得不处理 urls,blocker,new_urls ,这似乎不是一个好主意,尤其是当我不断喂食更多的东西时以及指向旧列表的更多链接,似乎并不太有效
  2. 让我们尝试将它们转换为列表! - 嘿!有效!只需3件物品? -进一步看,set already is a list? 但是,当我使用{ 'item' }作为集合而不是[ 'item' ]时出现错误?

好的,因此请选择以下第一组:

urls = {'facebook.com', 'youtube.com', 'gold'}
blocked = {'facebook'}
>> Set changed during iteration

好的,我们这样做:

urls = ['facebook.com', 'youtube.com', 'gold']
blocked = ['facebook']
>>> Removed: facebook

是的!

如果我们像这样添加更多的阻止器怎么办:

urls = ['facebook.com', 'youtube.com', 'gold']
blocked = ['facebook', 'youtube']
>>>Removed: facebook
   ['youtube.com', 'gold']

这很奇怪!出于某种原因,它只能去除一种阻滞剂?

如何获得黄金

2 个答案:

答案 0 :(得分:2)

我们可以进一步扩展您的方法,仅使用set操作即可达到您想要的目标。

found = set()
urls = {'facebook.com', 'youtube.com', 'gold'}
blocked = {'facebook', 'youtube'}

for url in urls:
    for blocker in blocked:
        if blocker in url:
            found.add(url)

urls.difference(found)

{'gold'}

答案 1 :(得分:1)

在迭代过程中更改列表/集的内容通常是灾难的秘诀。在几乎所有情况下,最好构造一个新的列表/集,而不要就地操作。这很容易理解:

urls = ['facebook.com', 'youtube.com', 'gold']
blocked = ['facebook', 'youtube']

urls = [url for url in urls if not any(blocker in url for blocker in blocked)]
print(urls)
# ['gold']

有套:

urls = {'facebook.com', 'youtube.com', 'gold'}
blocked = {'facebook', 'youtube'}

urls = {url for url in urls if not any(blocker in url for blocker in blocked)}
print(urls)
# {'gold'}

但是,请注意,遍历集合非常慢,而带有列表的选项可能会更快。