python - 将一个元素转换为一个元素的元组/列表/集合/字符串的简洁通用方法
问题描述
我遇到一个面试问题来实现以下功能:
def f(sequence_type, element):
pass
例如:
f(str, 'a') return 'a'
f(list, 'a') return ['a']
f(list, 'ab') return ['ab']
f(list, 1) return [1]
f(tuple, 1) return (1, )
f(set, 1) return {1}
f(str, 1) return '1'
f(str, [1]) return '[1]'
我想出了一个天真的方法:
def f(sequence_type, element):
return sequence_type(element)
此方法适用于str
. 但是,我会得到错误,因为tupe(1)
会 raise TypeError: 'int' object is not iterable
。
当然,我可以写一堆if else
检查类型并使用特定的方式来生成一个元素序列,例如[x]
(x,)
等等。有没有干净和通用的方法来做到这一点?
解决方案
You can approximate the requirement this way:
from collections.abc import Iterable
def f2(sequence_type, *elements):
if isinstance(elements[0],Iterable):
return sequence_type(elements[0])
else:
return sequence_type(elements[:1])
which is close, but fails for f(list, 'ab')
which returns ['a', 'b']
not ['ab']
It is hard to see why one would expect a Python function to treat strings of length 2 differently from strings of length 1. The language itself says that list('ab') == ['a', 'b']
.
I suspect that is an expectation imported from languages like C that treat characters and strings as different datatypes, in other words I have reservations about that aspect of the question.
But saying you don't like the spec isn't a recipe for success, so that special treatment has to be coded as such:
def f(sequence_type, elements):
if isinstance(elements, str) and len(elements) > 1 and sequence_type != str:
return sequence_type([elements])
else:
return f2(sequence_type, elements)
The result is generic but the special-casing can't really be called clean.
推荐阅读
- c# - WPF - 设置 DataContext 极大地增加了计算时间
- javascript - 检查用户是否对 Google Drive URL 具有“编辑权限”
- python - 如何将一个数字作为输入并在 Python 中打印一个浮点数直到该小数点
- java - iText7 LtvVerification.addVerification 未启用 LTV
- vector - openlayers 5中矢量图层的交互功能
- c# - C# 将两种不同类型的属性序列化为 JSON
- javascript - 为什么在 vuex 存储中推送到数组后未定义数组?
- c - 有效地将可被 3 或 5 整除的数字相加
- python - django 如何显示新添加产品的详细信息页面
- python - 在 Seaborn / Matplotlib 的小提琴图上指定高于和低于中位数的颜色