在 Python 中将字符串转换为字典
在处理配置文件、API 响应或数据处理时,将字符串转换为字典是一项常见任务。让我们探索在 Python 中将字符串转换为字典的所有实用方法。
基本字符串到字典的转换
对 JSON 字符串使用 json.loads()
将 JSON 格式的字符串转换为字典的最简单方法:
import json
# Simple JSON string
json_string = '{"name": "John", "age": 30, "city": "New York"}'
my_dict = json.loads(json_string)
print(my_dict) # Output: {'name': 'John', 'age': 30, 'city': 'New York'}
print(my_dict['name']) # Output: John
# Handle nested JSON
nested_json = '''{
"person": {
"name": "Alice",
"contacts": {
"email": "alice@email.com",
"phone": "123-456-7890"
}
}
}'''
nested_dict = json.loads(nested_json)
print(nested_dict['person']['contacts']['email']) # Output: alice@email.com
对字典字符串使用 ast.literal_eval()
对于 Python 字典格式的字符串:
from ast import literal_eval
# String representation of a dictionary
dict_string = "{'name': 'John', 'age': 30}"
my_dict = literal_eval(dict_string)
print(my_dict) # Output: {'name': 'John', 'age': 30}
# Works with various Python data types
complex_string = "{'numbers': [1, 2, 3], 'tuple': (4, 5, 6)}"
complex_dict = literal_eval(complex_string)
print(complex_dict['numbers']) # Output: [1, 2, 3]
解析自定义字符串格式
使用 split() 的键值对
转换简单的键值字符串:
# Simple key=value format
def parse_key_value(string):
"""Convert key=value string to dictionary"""
return dict(item.split('=') for item in string.split(';'))
# Example usage
config_string = "host=localhost;port=5432;user=admin"
config = parse_key_value(config_string)
print(config) # Output: {'host': 'localhost', 'port': '5432', 'user': 'admin'}
# Handle spaces and multiple separators
def parse_flexible(string, item_sep=';', key_sep='='):
"""Parse strings with flexible separators"""
items = (item.strip() for item in string.split(item_sep))
return dict(item.split(key_sep, 1) for item in items if item)
# Example with spaces
messy_string = "host = localhost; port= 5432; user =admin"
config = parse_flexible(messy_string)
print(config) # Output: {'host': 'localhost', 'port': '5432', 'user': 'admin'}
转换查询字符串
将 URL 查询字符串解析为字典:
from urllib.parse import parse_qs, urlparse
def parse_query_string(url):
"""Convert URL query string to dictionary"""
parsed = urlparse(url)
return parse_qs(parsed.query)
# Example usage
url = "https://example.com/search?name=John&age=30&city=New%20York"
params = parse_query_string(url)
print(params) # Output: {'name': ['John'], 'age': ['30'], 'city': ['New York']}
# For single values, unwrap the lists
def parse_query_single(url):
"""Convert URL query string to dictionary with single values"""
return {k: v[0] for k, v in parse_query_string(url).items()}
params = parse_query_single(url)
print(params) # Output: {'name': 'John', 'age': '30', 'city': 'New York'}
实际应用
配置解析器
创建灵活的配置解析器:
class ConfigParser:
def __init__(self):
self.config = {}
def parse_line(self, line):
"""Parse a single configuration line"""
line = line.strip()
if line and not line.startswith('#'):
key, *value = line.split('=', 1)
if value:
self.config[key.strip()] = value[0].strip()
def parse_string(self, string):
"""Parse multi-line configuration string"""
for line in string.split('\n'):
self.parse_line(line)
return self.config
# Example usage
config_string = """
# Database configuration
db_host = localhost
db_port = 5432
db_user = admin
# API configuration
api_key = xyz123
"""
parser = ConfigParser()
config = parser.parse_string(config_string)
print(config)
# Output: {'db_host': 'localhost', 'db_port': '5432',
# 'db_user': 'admin', 'api_key': 'xyz123'}
处理日志条目
将日志条目转换为字典:
import re
from datetime import datetime
def parse_log_entry(log_line):
"""Convert log line to structured dictionary"""
pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)'
match = re.match(pattern, log_line)
if match:
timestamp, level, message = match.groups()
return {
'timestamp': datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S'),
'level': level,
'message': message
}
return None
# Example usage
log_line = "2024-03-21 14:30:00 [ERROR] Database connection failed"
log_entry = parse_log_entry(log_line)
print(log_entry)
# Output: {
# 'timestamp': datetime(2024, 3, 21, 14, 30),
# 'level': 'ERROR',
# 'message': 'Database connection failed'
# }
解析 CSV 数据
将 CSV 行转换为字典:
import csv
from io import StringIO
def csv_to_dict_list(csv_string):
"""Convert CSV string to list of dictionaries"""
f = StringIO(csv_string)
return list(csv.DictReader(f))
# Example usage
csv_data = '''name,age,city
John,30,New York
Alice,25,London
Bob,35,Paris'''
records = csv_to_dict_list(csv_data)
print(records)
# Output: [
# {'name': 'John', 'age': '30', 'city': 'New York'},
# {'name': 'Alice', 'age': '25', 'city': 'London'},
# {'name': 'Bob', 'age': '35', 'city': 'Paris'}
# ]
错误处理和验证
安全的 JSON 解析
妥善处理 JSON 解析错误:
def safe_json_to_dict(json_string, default=None):
"""Safely convert JSON string to dictionary"""
try:
return json.loads(json_string)
except json.JSONDecodeError as e:
print(f"Error parsing JSON: {e}")
return default or {}
# Example usage
valid_json = '{"name": "John", "age": 30}'
invalid_json = '{"name": "John", age: 30}' # Missing quotes
print(safe_json_to_dict(valid_json))
# Output: {'name': 'John', 'age': 30}
print(safe_json_to_dict(invalid_json))
# Output: {} # Returns empty dict instead of raising error
类型转换和验证
将字符串值转换为适当的类型:
def convert_types(string_dict):
"""Convert string values to appropriate types"""
conversions = {
'int': int,
'float': float,
'bool': lambda x: x.lower() == 'true',
'null': lambda x: None if x.lower() == 'null' else x
}
def convert_value(value):
for type_name, converter in conversions.items():
try:
return converter(value)
except (ValueError, AttributeError):
continue
return value
return {k: convert_value(v) for k, v in string_dict.items()}
# Example usage
data = {
'age': '30',
'price': '19.99',
'active': 'true',
'description': 'Product details',
'stock': 'null'
}
converted = convert_types(data)
print(converted)
# Output: {
# 'age': 30,
# 'price': 19.99,
# 'active': True,
# 'description': 'Product details',
# 'stock': None
# }
要避免的常见错误
使用 eval() 而不是 ast.literal_eval()
# Wrong - security risk
dict_string = "{'name': 'John'}"
my_dict = eval(dict_string) # Never use eval() for parsing
# Right - safe parsing
from ast import literal_eval
my_dict = literal_eval(dict_string)
未处理缺失的键
# Wrong way
def parse_config(string):
parts = string.split(';')
return dict(part.split('=') for part in parts)
# Right way - handle missing values
def parse_config(string):
result = {}
for part in string.split(';'):
if '=' in part:
key, value = part.split('=', 1)
result[key.strip()] = value.strip()
return result
通过了解这些方法及其适当的使用案例,您可以有效地将字符串转换为 Python 中的字典,同时适当地处理错误和边缘情况。请记住选择最适合您的特定需求和数据格式的方法。