[英]How can I choose a specific intersection element in a list? TypeError: unhashed type: 'list'
我想交叉两个列表并打印它们的共同点。 但是,我想选择要相交的特定元素(例如[0]
或[hockeymatch]
、 [1]
等)。 对于 x[0] 或 y[1],我的意图不是匹配整行 select,而是只匹配 select [hockeymatch]。 我收到此错误:
TypeError: unhashable type: 'list'
在我的代码示例中,我想得到这个 output:
'Seattle-Minnesota', 'NHL', '18:00'
所以我只喜欢“西雅图-明尼苏达”、“NHL”、“18:00”,没有:
重要提示:这只是一个示例,但我会添加更多曲棍球比赛。 我不想仅通过设置 [('Seattle-Minnesota', 'NHL', '18:00')] 来手动打印,但我想“自动”打印任何共同的曲棍球比赛,甚至不止一场如果有的话,共同匹配)。
更新:对于 x[0] 或 y[1],我的意图不是 select 整场比赛,而是 select 仅 [hockeymatch],例如('Dallas-Arizona', 'NHL', '15: 00 ')] 或所有其他匹配项。 我想要一种方法能够将 select [hockeymatch]、[number1]、[number2] 与比赛放在同一行。
简单来说,我的意思是:
“考虑到将来会添加其他曲棍球比赛,寻找一个或多个常见的比赛(即 [hockeymatch]),但从交集 [number1] 和 [number2] 中排除”
代码:
#x = []
#x.append([[hockeymatch], [number1], [number2]])
x = [[[('Dallas-Arizona', 'NHL', '15:00')], [1.75], [87.5]],
[('Seattle-Minnesota', 'NHL', '18:00')], [2.5], [125.0]]
#y = []
#y.append([[hockeymatch], [number1], [number2]])
y = [[[('Seattle-Minnesota', 'NHL', '18:00')], [1.33], [62.0]],
[('Vancouver-Vegas', 'NHL', '20:00')], [0.50], [43.0]]
test = list(set(x[0]).intersection(y[0]))
print(test)
PS:为了使代码更加清晰,我在创建列表时添加了注释以及如何使用 append 插入元素
#x = []
#x.append([[hockeymatch], [tournament], [number1], [number2]])
x = [[[('Dallas-Arizona', 'NHL', '15:00')], [1.75], [87.5]],
[('Seattle-Minnesota', 'NHL', '18:00')], [2.5], [125.0]]
#y = []
#y.append([[hockeymatch], [tournament], [number1], [number2]])
y = [[[('Seattle-Minnesota', 'NHL', '18:00')], [1.33], [62.0]],
[('Vancouver-Vegas', 'NHL', '20:00')], [0.50], [43.0]]
t1 = []
t2 = []
for i in range(len(x)):
if i == 0:
t1.append(tuple(x[i][0]))
else:
try:
if len(x[i][0]) == 3:
t1.append(tuple(x[i]))
except:
pass
for i in range(len(y)):
if i == 0:
t2.append(tuple(y[i][0]))
else:
try:
if len(y[i][0]) == 3:
t2.append(tuple(y[i]))
except:
pass
print(list((set(t1).intersection(set(t2)))))
您可以使用函数简化代码
x = [[[('Dallas-Arizona', 'NHL', '15:00')], [1.75], [87.5]],
[('Seattle-Minnesota', 'NHL', '18:00')], [2.5], [125.0]]
y = [[[('Seattle-Minnesota', 'NHL', '18:00')], [1.33], [62.0]],
[('Vancouver-Vegas', 'NHL', '20:00')], [0.50], [43.0]]
t1 = []
t2 = []
def matches(your_l, l_used):
for i in range(len(l_used)):
if i == 0:
your_l.append(tuple(l_used[i][0]))
else:
try:
if len(l_used[i][0]) == 3:
your_l.append(tuple(l_used[i]))
except:
pass
matches(t1, x)
matches(t2, y)
print(list((set(t1).intersection(set(t2)))))
它应该是:
list(set(x[1]).intersection(y[0][0]))
#[('Seattle-Minnesota', 'NHL', '18:00')]
因为 x 和 y 是嵌套列表。 因此,当您直接在 2D 列表上应用set()
时会出错。
TypeError: unhashable type: 'list'
根据文档:
集合是不同的可散列对象的无序集合。 这些对象必须是可散列的,以便查找、添加和删除元素比每次执行这些操作时查看每个单独的元素更快。
列表不是可散列的(/不可变的)数据类型。 这意味着当您尝试将 x[0] 转换为一个集合时,您需要确保 x[0] 中的每个元素都是可哈希的(元组、集合等而不是列表)。 您可以将 x[0] 从列表更改为元组。 (圆括号而不是方括号)使事情正常进行。
此外,对于不需要更改(至少就地更改)的数据使用元组通常是个好主意。
x = [((('Dallas-Arizona', 'NHL', '15:00')), 1.75, 87.5), ...
编辑
进行此更改后,假设您要查找存储在 x 和 y 中的匹配项之间的共同匹配项。 你可以试试
x = [
(('da', 'nhl', '15:00'), 1.75, 87.5),
(('sm', 'nhl', '18:00'), 2, 3)
]
y = [
(('da', 'nhl', '15:00'), 1.75, 87.5),
(('sm', 'nhl', '18:00'), 2, 3),
(('fse', 'afww', '15:00'), 121.75, 187.5),
(('afae', 'awfwa', '18:00'), 21, 13)
]
x_set = set(x)
y_set = set(y)
common_matches = x_set.intersection(y_set)
print([match[0] for match in common_matches])
这应该打印:
[('da', 'nhl', '15:00'), ('sm', 'nhl', '18:00')]
可变list
让你很伤心。
让我们使用一些不可变的tuple
!
from collections import namedtuple
from operator import itemgetter
Game = namedtuple("Game", "match, league, time, num1, num2")
x = [
Game("Dallas-Arizona", "NHL", "15:00", 1.75, 87.5),
Game("Seattle-Minnesota", "NHL", "18:00", 2.5, 125.0),
]
y = [
Game("Seattle-Minnesota", "NHL", "18:00", 1.33, 62.0),
Game("Vancouver-Vegas", "NHL", "20:00", 0.50, 43.0),
]
def getter(n: int, games: list[Game]):
return list(map(itemgetter(n), games))
print(getter(0, x))
print(getter(0, y))
print("\nintersection:")
print(set(getter(0, x)) & set(getter(0, y)))
print("\nunion:")
print(set(getter(0, x)) | set(getter(0, y)))
output:
['Dallas-Arizona', 'Seattle-Minnesota']
['Seattle-Minnesota', 'Vancouver-Vegas']
intersection:
{'Seattle-Minnesota'}
union:
{'Seattle-Minnesota', 'Dallas-Arizona', 'Vancouver-Vegas'}
显示set
时,如果您查看 output 的sorted(... )
版本,通常会更容易阅读。
您的问题没有为业务概念命名,例如前三个字段表示什么或两个数字的含义。
如果愿意,您可以定义一个 3 元组,然后定义一个包含它的更大的命名元组。 如果您对其进行测试并发现它解决了您的用例,请随时发布此类源代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.