【问题标题】:How can I write a for-loop that iterates over various forms of iterables?如何编写一个迭代各种形式的可迭代对象的 for 循环?
【发布时间】:2021-01-01 08:15:54
【问题描述】:

我正在编写一个基本迭代两个列表乘积的 for 循环。在大多数情况下,定义了两个列表,因此迭代产品没有问题。但是,也存在未定义两个列表之一的情况。此外,可能存在两个列表都没有定义的情况。我可以在下面的代码sn-p中更改函数bar,使其只有一个处理各种情况的single for-loopwithout if statements吗?

import itertools

def foo(a, b):
    print(a, b)

def bar(lista, listb):
    # How can I make this function more concise?
    if lista and listb:
        for a, b in itertools.product(lista, listb):
            foo(a, b)
    elif lista:
        for a in lista:
            foo(a, listb)
    elif listb:
        for b in listb:
            foo(lista, b)
    else:
        foo(lista, listb)

print("Case #1. When both lists are defined.")
lista = [1, 2]
listb = [3, 4]
bar(lista, listb)

print("Case #2. When only lista defined.")
lista = [1, 2]
listb = None
bar(lista, listb)

print("Case #3. When only listb is defined.")
lista = None
listb = [3, 4]
bar(lista, listb)

print("Case #4. When neither of two list are defined.")
lista = None
listb = None
bar(lista, listb)

【问题讨论】:

  • 顺便说一句,itertools.product(*[lista, listb]) 是一种过度设计的写作方式itertools.product(lista, listb)
  • @juanpa.arrivillaga 感谢您的建议。按照您的建议更新了代码。

标签: python python-3.x for-loop itertools generic-programming


【解决方案1】:

只需提前检查并用可接受的替代值替换 None 值:

import itertools

def bar(lista, listb):
    if lista is None:
        lista = [None]
    if listb is None:
        listb = [None]
    for a, b in itertools.product(lista, listb):
        foo(a, b)

尽管 IMO,如果调用者必须处理将有效参数传递给 bar 会更好,并且 bar 假设输入始终为非无。

还有术语 nitpick,在所有情况下,listalistb 已定义,在某些情况下它们可以是 None。这与未定义不同。由于您在谈论函数的参数,它们将总是被定义

【讨论】:

  • 感谢您的回答。那我能说“listalistb被定义为None”吗?
  • @Han 当然,那是准确的
【解决方案2】:

请尝试以下功能。

def bar(lista, listb):
    for a, b in itertools.product(*[lista or [None], listb or [None]]):
        foo(a, b)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    相关资源
    最近更新 更多