Python学习遇sample larger than population错误及代码求助
嘿,这个错误我之前踩过坑,一眼就能看出问题所在——「sample larger than population」本质是你要抽取的样本数量,比目标集合里的元素总数还多,比如你只有5个元素的列表,却想抽10个样本,Python肯定会直接报错。
结合你给出的代码片段,我帮你梳理几个大概率的问题点和解决办法:
1. 列表元素添加方式错用了append而非extend
看你的代码里用了dictionary.append(DICTIONARY_SYMBOLS),但如果DICTIONARY_SYMBOLS、DICTIONARY_NUMBERS_DEC这些是列表类型(比如符号列表['!', '@', '#']),append会把整个列表作为单个元素塞进dictionary,而不是把列表里的元素逐个加进去。
举个例子:如果DICTIONARY_SYMBOLS有8个符号,用append后dictionary里只会多1个元素(就是这个符号列表),而不是8个单独的符号。这直接导致dictionary的实际元素数量远小于你预期的,后续调用抽样函数时自然会出现「样本数大于集合大小」的错误。
修正办法:把所有append换成extend,这样会把预定义列表里的元素逐个合并到dictionary中:
def get_segment(_len,dic): word_segment = '' dictionary = [] while dic > 0: if dic >= 8: dictionary.extend(DICTIONARY_SYMBOLS) # 替换append为extend dic -= 8 elif dic >= 4: dictionary.extend(DICTIONARY_NUMBERS_DEC) dic -= 4 elif dic >= 2: dictionary.extend(DICTIONARY_LETTERS_LOWER) dic -= 2 else: dictionary.extend(DICTIONARY_LETTERS_UPPER) dic -= 1 # 后续的scramble_li逻辑...
2. 抽样函数的使用不合理
你代码末尾的scramble_li...大概率是调用了random.sample()来打乱列表,但其实如果只是想打乱顺序,用random.shuffle()更合适(直接原地打乱列表,不需要指定抽样数量)。如果非要用sample,必须保证抽样数量k等于len(dictionary),而且要确保dictionary不为空:
import random # 推荐的打乱方式:原地打乱 random.shuffle(dictionary) # 如果一定要用sample,必须满足k <= len(dictionary) if dictionary: scrambled_dict = random.sample(dictionary, len(dictionary)) else: # 处理空列表的情况,避免报错 scrambled_dict = []
3. 预定义列表的长度可能不满足逻辑要求
你的逻辑是每次减8/4/2/1,默认认为DICTIONARY_SYMBOLS至少有8个元素、DICTIONARY_NUMBERS_DEC至少有4个元素,但如果这些预定义列表的实际长度不够,也会导致dictionary的元素数量不足。比如DICTIONARY_NUMBERS_DEC只有3个数字,那你减4之后,实际只加了3个元素,后续抽样时也会出问题。
补充优化:可以在代码里加个长度校验,避免这种情况:
def get_segment(_len,dic): word_segment = '' dictionary = [] while dic > 0: if dic >= 8 and len(DICTIONARY_SYMBOLS) >= 8: dictionary.extend(DICTIONARY_SYMBOLS) dic -= 8 elif dic >= 4 and len(DICTIONARY_NUMBERS_DEC) >= 4: dictionary.extend(DICTIONARY_NUMBERS_DEC) dic -= 4 elif dic >= 2 and len(DICTIONARY_LETTERS_LOWER) >= 2: dictionary.extend(DICTIONARY_LETTERS_LOWER) dic -= 2 elif dic >= 1 and len(DICTIONARY_LETTERS_UPPER) >= 1: dictionary.extend(DICTIONARY_LETTERS_UPPER) dic -= 1 else: # 处理预定义列表长度不足的情况,比如打印提示或者break print("注意:预定义字典的元素数量不足,无法满足需求") break # 后续逻辑...
按照上面的步骤调整后,应该就能解决这个错误啦。
内容的提问来源于stack exchange,提问作者Jason 'Slingshot' Miller

