迭代 Python 列表可能包括其他列表?



我有一些函数需要两个参数。我想遍历一对参数对的列表,并在每对参数上调用它:

arglist = [(arg1, 'Ni!'), (arg2, 'Peng!'), (arg3, 'Neee-Wom!')]
for arg in arglist:
func(arg[0], arg[1])
# The pairs don't have to be tuples, just showing that way for convenience

这里有一个转折 - 我希望能够让每个对的一个参数有时是一个列表,在这种情况下,整个迭代将遍历列表中的每个项目,调用它及其伙伴上的函数。所以这个:

newwords = ['Ekke', 'ekke', 'Ptang', 'Zoo', 'Boing']
arglist = [(arg1, 'Ni!'), (arg2, 'Peng!'), (arg3, 'Neee-Wom!'), (arg4, newwords)]
for arg in arglist:
func(arg[0], arg[1])

应该等效于这个:

arglist = [(arg1, 'Ni!'), (arg2, 'Peng!'), (arg3, 'Neee-Wom!'), (arg4, 'Ekke'), 
(arg4, 'Ekke'), (arg4, 'Ptang'), (arg4, 'Zoo'), (arg4, 'Boing')]
for arg in arglist:
func(arg[0], arg[1])

有没有一种很好的 Python 方法来做到这一点?

取决于该列表成对出现的频率。

如果频繁 - 去尝试 - 除了。

def try_except_method():
for arg, item in args_list:
try:
for i in item:  # assuming item is following sequence protocol.
do_something(arg, i)
except TypeError:  # asking for forgiveness.
do_something(arg, item)

这将在每次迭代中比测试条件运行得更快。

如果没有,请像其他答案一样使用"isinstance"检查条件。

def is_instance_method():
for arg, item in args_list:
if isinstance(item, list):
for i in item:
do_something(arg, i)
else:
do_something(arg, item)

作为奖励,如果您打算使用除列表和 str 以外的更多类型 - 选择"单次发送"。

@singledispatch  # all types other than registers goes here.
def func(a, b):
do_something(a, b)

@func.register(list)  # only list type goes here.
def func_list(a, b):
for i in b:
do_something(a, i)

def single_dispatched():
for arg, item in args_list:
func(arg, item)

示例中的每个方法所花费时间的结果。 尝试使用不同的数据来玩这些,这是完整的代码。

0.0021587999999999052
0.0009472000000001479
0.0024591000000000474

试试这个:

for arg, value in arglist:
if isinstance(value, list):
for v in value:
func(arg, v)
else:
func(arg, value)
def echo(x, y):
print(x, y)
newwords = ['Ekke', 'ekke', 'Ptang', 'Zoo', 'Boing']
arglist = [('arg1', 'Ni!'), ('arg2', 'Peng!'),
('arg3', 'Neee-Wom!'), ('arg4', newwords)]
for arg0, arg1 in arglist:
if isinstance(arg1, list):
for item in arg1:
echo(arg0, item)
else:
echo(arg0, arg1)

for arg0, arg1 in arglist:
echo(arg0, arg1) if not isinstance(arg1, list) else [
echo(arg0, item) for item in arg1]

isinstance((是帮助你做到这一点的那个。

您可以做的是,使用isinstance()来检查它是否是一个列表。并研究您可能的功能:

for arg in arglist:
# if the item is a list go through each item and pass it with the arg[0]
if isinstance(arg[1], type([])): 
# passing arg[0] and item from array item of arg[0]
for item in arg[1]: func(arg[0], item) 
else: func(arg[0], arg[1])

最新更新