Python 如何正确使用列表中的类型
我编写了一个函数,用集合替换列表中的所有元素Python 如何正确使用列表中的类型,python,python-3.x,list,set,Python,Python 3.x,List,Set,我编写了一个函数,用集合替换列表中的所有元素 def get_set(arr): 返回列表(映射(lambda x:set(x),arr)) 它通过例子起作用 A=[(0,3)、(0,4)、(3,4)] A=获取集合(A) 我们得到了 A=[{0,3},{0,4},{3,4}] 但是如果我用thif函数作为例子 B=[({0,3},{0,4}),({0,3},{3,4}),({0,4},{3,4})] 获取集合(B) 我犯了一个错误 in(x) 1个def get_设置(arr): --
def get_set(arr):
返回列表(映射(lambda x:set(x),arr))
它通过例子起作用
A=[(0,3)、(0,4)、(3,4)]
A=获取集合(A)
我们得到了
A=[{0,3},{0,4},{3,4}]
但是如果我用thif函数作为例子
B=[({0,3},{0,4}),({0,3},{3,4}),({0,4},{3,4})]
获取集合(B)
我犯了一个错误
in(x)
1个def get_设置(arr):
---->2返回列表(映射(lambda x:set(x),arr))
TypeError:无法损坏的类型:“set”
如何修复我的代码并获取
B=[{{0,3},{0,4},{{0,3},{3,4},{0,4},{3,4}]
B中的每个元素都是集合的元组。您可以使用可散列的。
所以每个元素都可以散列,并且可以转换为一个集合
def get_set(arr):
return list(map(set, arr))
B=[
(frozenset([0, 3]), frozenset([0, 4])),
(frozenset([0, 3]), frozenset([3, 4])),
(frozenset([0, 4]), frozenset([3, 4]))
]
B=get_set(B)
print(B)
输出
[set([frozenset([0, 4]), frozenset([0, 3])]), set([frozenset([3, 4]), frozenset([0, 3])]), set([frozenset([3, 4]), frozenset([0, 4])])]
def get_设置(arr):
返回列表(映射(lambda x:set(x),arr))
它通过例子起作用
A=[(0,3)、(0,4)、(3,4)]
A=获取集合(A)
我们得到了
A=[{0,3},{0,4},{3,4}]
但是如果我用thif函数作为例子
B=[({0,3},{0,4}),({0,3},{3,4}),({0,4},{3,4})]
获取集合(B)
我犯了一个错误
in(x)
1个def get_设置(arr):
---->2返回列表(映射(lambda x:set(x),arr))
TypeError:unhabable type:'set'简单的回答是错误告诉了您一切:像
set
、dict
、list
等元素是不可散列的,因为它们是可变的。这意味着你不能用它们来构建一个集合
但这当然不是故事的结局。只要以对象模型允许的方式显式分配含义,就可以有意义地构建一组您想要的内容。例如,您可以创建不可破坏类型到返回适当替代或包装的函数的映射:
type_map = {
list: tuple,
set: frozenset,
dict: lambda x: tuple(x.items()),
bytearray: bytes,
}
如果课程adict
仅在您计划对表单进行类型检查时才完全有用type(x)=y
,而不是使用更惯用的isinstance
。然而,即使在后一种情况下,dict
也可以作为一个很好的成对容器
一个更普遍的解决方案可能是
def wrap_type(x):
"""
Attempt to turn `x` into a hashable type using registry in `type_map`.
The result is not guaranteed to be hashable.
"""
for t, w in type_map.items():
if isinstance(x, t):
return w(x)
return x
def transform_set(i):
return set(wrap_type(x) for x in i)
def get_set(i):
return list(map(transform_set, i))
此实现有(至少)一个缺陷:wrap\u类型
不是递归的。它可能会正确地将所有列表转换为元组,但如果任何元素都不可散列,则无法使结果可散列。该问题仅适用于某些类型,如list
、dict
,甚至tuple
,但不适用于bytearray
或set
您可以通过实现type\u map
以包括递归来避免这种情况:
from collections.abc import Sequence, Mapping, Set
def wrap_seq(s):
return tuple(wrap_type(x) for x in s)
def wrap_map(m):
return tuple((k, wrap_type(v)) for k, v in m.items())
type_map = {
Sequence: wrap_seq,
Set: frozenset,
Mapping: warp_map,
}
请注意:
lambda x:set(x)
和set
之间没有实际的区别。简单的回答是你不能:集合是可变的,因此是不可破坏的。