Python案例如何校验数据唯一性?

wen python案例 69

本文目录导读:

Python案例如何校验数据唯一性?

  1. 使用集合(Set)校验唯一性
  2. 使用字典校验复杂数据
  3. 使用Pandas处理大型数据集
  4. 数据库唯一性校验
  5. 自定义对象唯一性校验
  6. 实时校验(表单输入)
  7. 性能比较
  8. 最佳实践建议

在Python中校验数据唯一性有多种方法,以下是一些常见案例:

使用集合(Set)校验唯一性

基本列表去重

def check_unique(data_list):
    """检查列表中是否有重复元素"""
    return len(data_list) == len(set(data_list))
# 示例
data = [1, 2, 3, 4, 5]
print(check_unique(data))  # True
data_with_duplicate = [1, 2, 3, 2, 4]
print(check_unique(data_with_duplicate))  # False

找出重复元素

def find_duplicates(data_list):
    """找出列表中的重复元素"""
    seen = set()
    duplicates = set()
    for item in data_list:
        if item in seen:
            duplicates.add(item)
        else:
            seen.add(item)
    return list(duplicates)
data = [1, 2, 3, 2, 4, 3, 5]
print(find_duplicates(data))  # [2, 3]

使用字典校验复杂数据

校验字典列表中的唯一性

def validate_dict_uniqueness(data_list, key_field):
    """根据特定字段校验字典列表的唯一性"""
    seen_keys = {}
    duplicates = []
    for index, item in enumerate(data_list):
        key_value = item.get(key_field)
        if key_value in seen_keys:
            duplicates.append({
                'index1': seen_keys[key_value],
                'index2': index,
                'key': key_value,
                'value1': item,
                'value2': data_list[seen_keys[key_value]]
            })
        else:
            seen_keys[key_value] = index
    return {
        'is_unique': len(duplicates) == 0,
        'duplicates': duplicates,
        'total_items': len(data_list)
    }
# 示例
users = [
    {'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},
    {'id': 2, 'name': 'Bob', 'email': 'bob@example.com'},
    {'id': 3, 'name': 'Alice', 'email': 'alice2@example.com'},  # 名字相同
    {'id': 4, 'name': 'Charlie', 'email': 'bob@example.com'}    # 邮箱相同
]
# 按名字校验
result = validate_dict_uniqueness(users, 'name')
print(f"名称是否唯一: {result['is_unique']}")
print(f"重复项: {result['duplicates']}")

使用Pandas处理大型数据集

DataFrame去重检查

import pandas as pd
def check_pandas_uniqueness(df, columns=None):
    """检查DataFrame的唯一性"""
    if columns:
        # 检查特定列的组合是否唯一
        duplicates = df[df.duplicated(subset=columns, keep=False)]
    else:
        # 检查整行是否唯一
        duplicates = df[df.duplicated(keep=False)]
    return {
        'is_unique': len(duplicates) == 0,
        'duplicate_count': len(duplicates),
        'duplicate_data': duplicates
    }
# 示例
data = {
    'id': [1, 2, 3, 1, 5],
    'name': ['Alice', 'Bob', 'Charlie', 'Alice', 'Eve'],
    'department': ['HR', 'IT', 'IT', 'HR', 'Finance']
}
df = pd.DataFrame(data)
# 检查id列的唯一性
result = check_pandas_uniqueness(df, ['id'])
print(f"ID是否唯一: {result['is_unique']}")
print(f"重复ID的数据:\n{result['duplicate_data']}")

数据库唯一性校验

SQLite唯一性检查

import sqlite3
def check_database_uniqueness(db_path, table, column):
    """检查数据库表中的唯一性约束"""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    # 查找重复值
    cursor.execute(f"""
        SELECT {column}, COUNT(*) as count 
        FROM {table} 
        GROUP BY {column} 
        HAVING COUNT(*) > 1
    """)
    duplicates = cursor.fetchall()
    conn.close()
    return {
        'is_unique': len(duplicates) == 0,
        'duplicate_values': duplicates
    }
# 示例(需要先创建数据库和表)
# result = check_database_uniqueness('example.db', 'users', 'email')
# print(f"邮箱是否唯一: {result['is_unique']}")

自定义对象唯一性校验

使用eqhash方法

class User:
    def __init__(self, user_id, email):
        self.user_id = user_id
        self.email = email
    def __eq__(self, other):
        if not isinstance(other, User):
            return False
        return (self.user_id == other.user_id or 
                self.email == other.email)
    def __hash__(self):
        # 注意:这里为了简单,只用user_id做哈希
        return hash(self.user_id)
    def __repr__(self):
        return f"User({self.user_id}, {self.email})"
def validate_objects_uniqueness(objects, attribute='user_id'):
    """校验对象列表的唯一性"""
    seen = {}
    duplicates = []
    for obj in objects:
        key = getattr(obj, attribute)
        if key in seen:
            duplicates.append((seen[key], obj))
        else:
            seen[key] = obj
    return {
        'is_unique': len(duplicates) == 0,
        'duplicates': duplicates
    }
# 示例
users = [
    User(1, 'alice@example.com'),
    User(2, 'bob@example.com'),
    User(1, 'alice2@example.com'),  # 重复user_id
    User(3, 'bob@example.com')      # 重复email(但hash不同)
]
result = validate_objects_uniqueness(users, 'email')
print(f"邮箱是否唯一: {result['is_unique']}")
print(f"重复的邮箱用户: {result['duplicates']}")

实时校验(表单输入)

def validate_real_time_input(existing_data, new_value):
    """实时校验输入的唯一性"""
    if new_value in existing_data:
        return {
            'valid': False,
            'message': f"'{new_value}' 已存在,请输入其他值"
        }
    else:
        existing_data.add(new_value)
        return {
            'valid': True,
            'message': f"'{new_value}' 是唯一的"
        }
# 示例
existing_emails = {'alice@example.com', 'bob@example.com'}
result = validate_real_time_input(existing_emails, 'alice@example.com')
print(result['message'])  # 'alice@example.com' 已存在
result = validate_real_time_input(existing_emails, 'charlie@example.com')
print(result['message'])  # 'charlie@example.com' 是唯一的

性能比较

import time
import random
import string
def generate_large_dataset(size=100000):
    """生成大型测试数据"""
    return [random.randint(1, size//2) for _ in range(size)]
# 比较不同方法的性能
def compare_methods():
    data = generate_large_dataset(100000)
    # 方法1: 使用集合
    start = time.time()
    is_unique = len(data) == len(set(data))
    set_time = time.time() - start
    # 方法2: 使用排序
    start = time.time()
    sorted_data = sorted(data)
    has_duplicates = any(sorted_data[i] == sorted_data[i+1] 
                        for i in range(len(sorted_data)-1))
    sort_time = time.time() - start
    print(f"集合方法: {set_time:.4f}秒")
    print(f"排序方法: {sort_time:.4f}秒")
    print(f"有没有重复: {not is_unique}")
# compare_methods()

最佳实践建议

  1. 小数据集:使用集合(set)方法,简单高效
  2. 大数据集:考虑使用Pandas或数据库层面校验
  3. 实时系统:结合缓存和索引提高性能
  4. 关键数据:业务逻辑中做双层校验(内存+数据库)
  5. 错误处理:提供清晰的错误信息和修复建议

选择哪种方法取决于你的数据规模、性能要求和业务复杂度。

抱歉,评论功能暂时关闭!