Python lambda 函数,遍历元组和列表



假设你有一个包含属性的类表: 记录(字典列表( 和键,这是每个表的主键(就像 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==51customer_id==10就像记录中的第一个字典一样(单位无关紧要,因为它不是键(。

然而:

{'product_id': 51, 'customer_id' : 11, 'units':9}

将返回False,因为没有包含product_id==51customer_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)

简单地使用anyall就可以解决问题:">检查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
)
)

如果您不被"允许"使用anyall,可以按如下方式替换它们:

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
)

最新更新