一、什么是combinations
combinations是Python中的一个函数,它可以返回指定序列中所有长度为n的组合。它的语法如下:
combinations(iterable, r)
其中,iterable表示要求组合的序列;r表示每个组合的长度,通常也称为组合数。
下面是一个简单的例子:
from itertools import combinations lst = ['a', 'b', 'c'] for i in combinations(lst, 2): print(i)
输出结果为:
('a', 'b') ('a', 'c') ('b', 'c')
二、如何使用combinations
1、生成组合列表
combinations可以生成长度为n的组合列表,我们可以将它们存储在一个列表中,以备后续使用。下面是一个例子,我们要取出列表[1, 2, 3, 4]中长度为3的所有组合:
from itertools import combinations lst = [1, 2, 3, 4] res = [] for i in range(1, len(lst) + 1): res.extend(list(combinations(lst, i))) print(res)
输出结果为:
[(1,), (2,), (3,), (4,), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), (1, 2, 3, 4)]
2、使用combinations生成器
如果我们对生成的组合仅仅是遍历取值,不需要将所有组合存储在列表中,那么可以使用combinations生成器,这样可以节约存储空间和计算时间,如下所示:
from itertools import combinations lst = [1, 2, 3, 4] for i in range(1, len(lst) + 1): for j in combinations(lst, i): print(j)
输出结果与上面的例子相同。
3、使用combinations计算总数
在某些情况下,我们需要计算给定列表中组合的总数,这时候可以使用组合数公式。
设有n个元素,要在其中选出r个元素的组合,其组合数为C(n, r)。组合数公式如下:
C(n, r) = n! / (r! * (n - r)!)
下面是一个例子,我们要从列表[1, 2, 3, 4]中选出2个元素的组合,那么总数为:
import math n = 4 # 元素数量 r = 2 # 组合数 res = math.factorial(n) // (math.factorial(r) * math.factorial(n - r)) print(res)
输出结果为:
6
三、combinations的应用场景
1、密码破解
combinations可以用于密码破解。我们可以生成不同长度的密码组合,进行暴力破解。
import itertools import string # 生成长度为n的密码组合 def generate_password(n): symbols = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+"] all_chars = string.ascii_letters + string.digits + "".join(symbols) for password in itertools.combinations(all_chars, n): yield "".join(password) # 假设密码长度为6 password_length = 6 # 生成所有长度为6的密码组合 passwords = generate_password(password_length) # 破解密码 real_password = "abc123" for password in passwords: if password == real_password: print(f"The password is {password}") break
如果将上面的程序运行,可以得到正确的密码“abc123”。
2、数据分析
combinations可以用于数据分析,特别是在大量数据中查找特定的元素组合时非常有用。例如,在一个大的文本文件中,查找特定单词组合的出现次数。
import itertools import re # 读取文本文件 def read_text_file(file_path): with open(file_path, "r", encoding="utf-8") as f: return f.read() # 统计单词出现次数 def count_word_occurrences(file_path, word_count): # 读取文本文件 text = read_text_file(file_path) # 使用正则表达式将文本文件中的单词清洗出来 words = re.findall(r'\w+', text) # 统计单词出现次数 for word in itertools.combinations(words, word_count): key = " ".join(word) if key not in word_counts: word_counts[key] = 0 word_counts[key] += 1 return word_counts # 假设我们要在文本文件中查找长度为3的单词组合 word_count = 3 # 统计单词出现次数 word_counts = count_word_occurrences("text.txt", word_count) # 打印结果 for key, value in word_counts.items(): print(f"{key}: {value}")
上面的程序可以在文本文件”test.txt”中查找长度为3的单词组合的出现次数。
3、百度贴吧数据爬取
combinations可以用于爬取百度贴吧数据。我们可以通过多个关键词构造不同的搜索组合,爬取相关帖子。
import itertools import requests from bs4 import BeautifulSoup # 构造搜索url def build_search_url(keywords, page_num): return f"https://tieba.baidu.com/f?kw={'%20'.join(keywords)}&ie=utf-8&pn={(page_num - 1) * 50}" # 爬取搜索页数据 def get_search_data(keywords, page_num): search_url = build_search_url(keywords, page_num) response = requests.get(search_url) return response.text # 解析搜索页数据 def parse_search_data(search_data): soup = BeautifulSoup(search_data, "html.parser") return soup.select(".threadlist_title a") # 假设我们要搜索以下两个关键词组合的贴吧帖子: keywords = ["Python", "机器学习"] # 假设我们要爬取的页数为2 page_count = 2 # 爬取数据并解析 all_titles = [] for i in range(1, page_count + 1): search_data = get_search_data(keywords, i) titles = parse_search_data(search_data) all_titles.extend(titles) # 打印结果 for title in all_titles: print(title.text.strip())
上面的程序可以爬取关键词“Python”和“机器学习”的贴吧帖子标题。