假设你有一个包含属性的类表: 记录(字典列表( 和键,这是每个表的主键(就像 SQL( - 元组
我需要编写一个 lambda 函数,该函数接受一个新行,然后如果新行中键的所有值都吐出 True 或 False 已在表中
例如:
# Table: orders
keys = ('product_id', 'customer_id')
records: [{'product_id': 51, 'customer_id' : 10, 'units':9},
{'product_id': 32, 'customer_id' : 11, 'units':33},
{'product_id': 39, 'customer_id' : 47, 'units':2}]
现在我们要检查的新行是:
{'product_id': 51, 'customer_id' : 10, 'units': 77 }
这将返回True
因为product_id==51
和customer_id==10
就像记录中的第一个字典一样(单位无关紧要,因为它不是键(。
然而:
{'product_id': 51, 'customer_id' : 11, 'units':9}
将返回False
,因为没有包含product_id==51
和customer_id==11
的行
我们必须使用 lambda 函数(我们不必使用过滤器,只是一个提示(
我已经尝试了很多许多不同的方法来"攻击"这个问题,但我无法同时迭代键列表和一个元组......
contains_key = lambda self, new_row: list(filter(
(lambda con: con[self.__key]),
[record for record in self.__records]
))
说明:self 是我们进行操作的表,new_row是要检查
的行(字典(,self.__keys是键的元组(如 sql 中的主键(,self.__records是字典列表=""sql 表中的行""(
函数在类 Table 内(这就是为什么它是"self"形式(
class Table:
def __init__(self, key_set):
self.__key = tuple(key_set)
self.__records = []
def add_record(self, new_record):
self.__records.append(new_record)
简单地使用any
和all
就可以解决问题:">检查any
记录的all
键是否与新记录相同">:
print(any(all(new_record[key] == record[key] for key in keys) for record in records))
这些功能的好处是短路:每当键不匹配时 - 记录将被跳过,当记录匹配时 - 不再检查记录。
我将把它留给你,作为一种练习,把它变成一个lambda
:)
像这样的东西,似乎是:
class Table:
def __init__(self, key):
# using the __ in an odd way
self.__key = key
self.__records = []
# only using lambda because you must, it's pointless
contains_key = lambda self, record: any(all(record[f] == r[f] for f in self.__key) for r in self.__records)
def add(self, record):
if not self.contains_key(record):
self.__records.append(record)
else:
raise Exception('duplicate key')
t = Table(('product_id', 'customer_id'))
t.add({'product_id': 51, 'customer_id': 10, 'units': 9})
t.add({'product_id': 32, 'customer_id': 11, 'units': 33})
t.add({'product_id': 39, 'customer_id': 47, 'units': 2})
# fails
t.add({'product_id': 39, 'customer_id': 47, 'units': 2})
但如果这是他们教你的,我会寻找一个更好的课程。
如果我替换:
# fails
t.add({'product_id': 39, 'customer_id': 47, 'units': 2})
跟
t.add({'customer_id': '13', 'product_id': '1234-5', 'units': 9})
print(t.contains_key({'customer_id': '13', 'product_id': '1234-5', 'units': 3}))
结果是True
.
这是一个规范的答案:
def has_row(records, keys, row):
return any(
all(row[k] == x[k] for k in keys)
for x in records
)
转换为"lambda 函数"是微不足道的:
has_row = (lambda records, keys, row:
any(
all(row[k] == x[k] for k in keys)
for x in records
)
)
如果您不被"允许"使用any
或all
,可以按如下方式替换它们:
any = (lambda xs:
bool(next(filter(lambda x: x, xs), False))
)
# Alternatively, without using next:
any = (lambda xs:
len(list(filter(lambda x: x, xs))) != 0
)
all = (lambda xs:
len(list(filter(lambda x: not x, xs))) == 0
)