这是一个荒谬而又怪异的用例,但请耐心接受,我对清单的理解是这样的:
"reading_types": [
{
"name": rt.reading_type,
"value": rt.reading_type_id,
}
for unit in item.units
for rt in unit.reading_types
],
在后端api调用中。 效果很好,因为最终结果几乎总是重复。如何确保不返回任何重复项?
这实际上是在另一个列表推导内部发生的,我无法在任何时候引用列表来删除重复项,因此我必须在列表推导本身内这样做。
我尝试使用set
:
set([
{
"name": rt.reading_type,
"value": rt.reading_type_id,
}
for unit in item.units
for rt in unit.reading_types
])
但这会导致错误:unhashable type: dict
答案 0 :(得分:6)
这个想法是使您的结构可哈希而不破坏得太多,因此您可以将它们恢复到原来的状态。
您可以将字典转换为dict_items
,然后转换为tuples
(现在我们可以将其放入set
,因为数据是可哈希的),在其上应用set
,并转换回字典:
input_list = [{"name":"name1","id":"id1"},{"name":"name2","id":"id2"},
{"name":"name1","id":"id1"}]
output_list = [dict(items) for items in {tuple(a.items()) for a in input_list}]
之所以可行,是因为子字典的值是可哈希的(字符串)。如果它们是字典,我们也必须将其转换。
结果:
[{'id': 'id1', 'name': 'name1'}, {'id': 'id2', 'name': 'name2'}]
Jon Clements的另一种解决方案,不使用set
,而是构建字典(使用字典理解),并使用键唯一性来破坏重复项,然后仅提取值:
list({tuple(d.items()):d for d in input_list}.values())
答案 1 :(得分:2)
您可以在set
中使用namedtuple
代替字典。作为namedtuple
的不可变对象,它们是可哈希的,而字典则不是。您还可以直接使用集合理解:
from collections import namedtuple
reading_type = namedtuple("reading_type", ["name", "value"])
{reading_type(rt.reading_type, rt.reading_type_id)
for unit in item.units
for rt in unit.reading_types}
答案 2 :(得分:0)
这不是列表理解,但是您可以使用<?php
header('Content-type: application/json');
include('connect.php');
$obj = json_decode(file_get_contents('php://input'), TRUE);
$gymId = $obj['gym_id'];
$query = "select * from tbl_fees where gym_id = $gymId";
$result = mysqli_query($sql, $query);
$row = $result->fetch_assoc();
$amount = $row['month'.$months];
echo json_encode($row);
?>
unique_everseen
recipe,也可以在第三方库中使用,例如more_itertools.unique_everseen
:
itertools
诀窍是确保您可以对字典进行哈希处理,这是通过将每个字典转换为已排序的元组的元组来执行的。在内部,该算法通过维持“可见的” from more_itertools import unique_everseen
input_list = [{"name":"name1","id":"id1"},{"name":"name2","id":"id2"},
{"name":"name1","id":"id1"}]
res = list(unique_everseen(input_list, key=lambda d: tuple(sorted(d.items()))))
print(res)
[{'name': 'name1', 'id': 'id1'}, {'name': 'name2', 'id': 'id2'}]
值并仅产生未出现在set
中的值来进行工作,否则将其添加。
答案 3 :(得分:-1)
您可以将整个列表包装在另一个理解中,以repr
的每个条目使用,并在其上使用set
:
set([repr(val) for val in [...]])