通过带条件的生成器表达式分配两个变量?
Assign two variables via generator expression w/ conditional?
下面的代码有一个包含各种奶酪及其数量的字典。根据预先确定的销售项目列表,代码然后打印出正在销售的奶酪总量与全价。
我正在使用生成器表达式来计算总数,但我想知道是否有一种方法可以压缩我的代码以某种方式同时分配 sale_count
和 full_price_count
变量if-else 条件,因为生成器的代码实际上是相同的。
cheeses = {'gouda': 3, 'cheddar': 7, 'american': 2, 'mozzarella': 5}
on_sale = ['american', 'blue cheese', 'cheddar', 'provolone', 'swiss']
# if the cheese is on sale, add its quantity to sale_count
# otherwise, add its quantity to full_price_count
sale_count = sum(qty for (cheese, qty) in cheeses.items() if cheese in on_sale)
full_price_count = sum(qty for (cheese, qty) in cheeses.items() if cheese not in on_sale)
print("Sale count: {}\nFull price count: {}".format(sale_count, full_price_count))
它的可读性不是很好,但是它在一行中完成了你想要的:
[sale_count, full_price_count] = map(sum, zip(*[(qty, 0) if cheese in on_sale else (0, qty) for cheese, qty in cheeses.items()]))
可以用一个表达式完成,如:
functools.reduce(
lambda x, y: (x[0] + y[0], x[1] + y[1]),
((qty, 0) if cheese in on_sale else (0, qty) for cheese, qty in cheeses.items()),
(0, 0))
但是,与其他可能的答案一样,这可能真的可以回答为什么当两个完全清楚时,并不总是必须简化为一个表达式。
另一种方法如下,但我同意@donkopotamus 的观点,如果你不担心性能问题,wo 表达式就可以了。
sale_count, full_price_count = map(sum, zip(*((v * (c in on_sale), v * (c not in on_sale)) for c, v in cheeses.items())))
下面的代码有一个包含各种奶酪及其数量的字典。根据预先确定的销售项目列表,代码然后打印出正在销售的奶酪总量与全价。
我正在使用生成器表达式来计算总数,但我想知道是否有一种方法可以压缩我的代码以某种方式同时分配 sale_count
和 full_price_count
变量if-else 条件,因为生成器的代码实际上是相同的。
cheeses = {'gouda': 3, 'cheddar': 7, 'american': 2, 'mozzarella': 5}
on_sale = ['american', 'blue cheese', 'cheddar', 'provolone', 'swiss']
# if the cheese is on sale, add its quantity to sale_count
# otherwise, add its quantity to full_price_count
sale_count = sum(qty for (cheese, qty) in cheeses.items() if cheese in on_sale)
full_price_count = sum(qty for (cheese, qty) in cheeses.items() if cheese not in on_sale)
print("Sale count: {}\nFull price count: {}".format(sale_count, full_price_count))
它的可读性不是很好,但是它在一行中完成了你想要的:
[sale_count, full_price_count] = map(sum, zip(*[(qty, 0) if cheese in on_sale else (0, qty) for cheese, qty in cheeses.items()]))
可以用一个表达式完成,如:
functools.reduce(
lambda x, y: (x[0] + y[0], x[1] + y[1]),
((qty, 0) if cheese in on_sale else (0, qty) for cheese, qty in cheeses.items()),
(0, 0))
但是,与其他可能的答案一样,这可能真的可以回答为什么当两个完全清楚时,并不总是必须简化为一个表达式。
另一种方法如下,但我同意@donkopotamus 的观点,如果你不担心性能问题,wo 表达式就可以了。
sale_count, full_price_count = map(sum, zip(*((v * (c in on_sale), v * (c not in on_sale)) for c, v in cheeses.items())))