一、什么是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”和“机器学习”的贴吧帖子标题。

