【问题标题】:Is there a way to zip inner elements of a list/tuple in python?有没有办法在 python 中压缩列表/元组的内部元素?
【发布时间】:2020-06-21 10:24:12
【问题描述】:

我遇到了一个要解决的简单 python 问题:拥有 3 类项目及其对应值的列表,打印出 3 个列表中总价值低于 X 的所有组合。(代码示例可能更清晰的解释) .

我已经设法使用 zip() 和 itertools.product() 创建组合来解决这个问题,但是在输出正确的组合时,我觉得必须有一种更好、更 Pythonic 的方式来表达通过压缩产品的内部元组来输出价格总和,而无需创建 2 个显式生成器/列表(我相信在这种情况下用例无关紧要)。来自 Java 背景,我有时仍然会遇到问题,没有陷入类似 Java 的语法,这是我绝对希望使用 Python 避免的。

这是我的代码:

import itertools

# Print out all possible meal combinations under $30

main_courses = ['beef stew', 'fried fish']
price_main_courses = [28, 23]

desserts = ['ice-cream', 'cake']
price_desserts = [2, 4]

drinks = ['cola', 'wine']
price_drinks = [3, 10]

products = itertools.product(
    zip(main_courses, price_main_courses),
    zip(desserts, price_desserts),
    zip(drinks, price_drinks)
)

for combo in products:
    names = (x[0] for x in combo)
    price = sum((x[1] for x in combo))
    if price <= 30:
        print(*names, price)

【问题讨论】:

    标签: python list generator


    【解决方案1】:

    基于this,for循环可以写成:

    for combo in products:
        names, prices = zip(*combo)
        price = sum(prices)
        if price <= 30:
            print(*names, price)
    

    【讨论】:

    • 我不知道 zip 可以这样工作。这几乎正​​是我想要的。
    【解决方案2】:

    嗯,我要做的唯一不同的事情是使用列表推导而不是 for 循环,例如:

    import itertools
    
    # Print out all possible meal combinations under $30
    
    main_courses = ['beef stew', 'fried fish']
    price_main_courses = [28, 23]
    
    desserts = ['ice-cream', 'cake']
    price_desserts = [2, 4]
    
    drinks = ['cola', 'wine']
    price_drinks = [3, 10]
    
    products = itertools.product(
        zip(main_courses, price_main_courses),
        zip(desserts, price_desserts),
        zip(drinks, price_drinks)
    )
    
    combos = [
        combo for combo in products if sum(price for name, price in combo) <= 30
    ]
    
    for combo in combos:
        print(' + '.join(name for name, price in combo), '=', sum(price for name, price in combo))
    
    >>> "fried fish + ice-cream + cola = 28"
    >>> "fried fish + cake + cola = 30"
    

    【讨论】:

      【解决方案3】:

      你可以使用列表推导

      result = [(m, de, dr) for (m, mp), (de, dep), (dr, drp) in products if mp + dep + drp <= 30 ]
      

      或者您可以通过使用dict 来操作您的数据结构来存储您的产品名称和价格,而不是使用 2 个列表:

      import itertools
      
      # Print out all possible meal combinations under $30
      main_courses_price = {'beef stew': 28, 'fried fish': 23}
      desserts_price = {'ice-cream': 2, 'cake': 4}
      drinks_price = {'cola': 3, 'wine': 10}
      
      full_prices = {**main_courses_price, **desserts_price, **drinks_price}
      products = itertools.product(main_courses_price, desserts_price, drinks_price)
      
      
      print(*(t for t in products if sum(map(full_prices.get, t)) <= 30), sep='\n')
      

      输出:

      ('fried fish', 'ice-cream', 'cola')
      ('fried fish', 'cake', 'cola')
      

      【讨论】:

        猜你喜欢
        • 2021-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-17
        相关资源
        最近更新 更多