Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过带条件的生成器表达式分配两个变量?_Python_Python 3.x_Generator_Generator Expression - Fatal编程技术网

Python 通过带条件的生成器表达式分配两个变量?

Python 通过带条件的生成器表达式分配两个变量?,python,python-3.x,generator,generator-expression,Python,Python 3.x,Generator,Generator Expression,下面的代码有一个包含各种奶酪及其数量的字典。根据预先确定的销售项目列表,代码然后打印销售的奶酪总量与全价 我正在使用生成器表达式来计算总数,但我想知道是否有一种方法可以压缩我的代码,在某种if-else条件下同时分配sale\u count和full\u price\u count变量,因为生成器的代码实际上是相同的 cheeses = {'gouda': 3, 'cheddar': 7, 'american': 2, 'mozzarella': 5} on_sale = ['american'

下面的代码有一个包含各种奶酪及其数量的字典。根据预先确定的销售项目列表,代码然后打印销售的奶酪总量与全价

我正在使用生成器表达式来计算总数,但我想知道是否有一种方法可以压缩我的代码,在某种if-else条件下同时分配
sale\u count
full\u price\u count
变量,因为生成器的代码实际上是相同的

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())))

不是真的。然而,减少行数不应该是清理代码的目标。这看起来像是好的、清晰的代码。很明显,每个部分都在做什么。如果你担心速度,你最大的改进就是将
on_sale
从一个列表切换到一个集合。如果你真的有大量的数据,与其在字典上迭代两次,不如利用If-else条件在字典上迭代一次,然后在最后对结果列表求和。