【问题标题】:How to 'hide' an element in a list when passing list to a function in Python?将列表传递给Python中的函数时如何“隐藏”列表中的元素?
【发布时间】:2016-12-02 23:13:35
【问题描述】:

假设我有一个列表

myList = [a,b,c,d,e]

还有一个函数

def doSomething(list):
    #Does something to the list

我想像这样迭代地调用函数:

doSomething([b,c,d,e])
doSomething([a,c,d,e])
doSomething([a,b,d,e])
doSomething([a,b,c,e])
doSomething([a,b,c,d])

首先想到的是这样的:

for x in range(0,len(myList)):
    del myList[x]
    doSomething(myList)

但这并没有真正起作用,因为每次我调用 del 它实际上都会删除元素。每次调用该函数时,我都想“隐藏”该元素。有没有办法做到这一点?

【问题讨论】:

  • 复制列表并从中删除?
  • @AndrasDeak 我认为这可能是一种方法,但是对于大型列表,我会像每次调用函数时一样复制列表,这不会花费大量时间吗?另外..如何再次复制列表?
  • 好吧,对于大型列表,是的,它可能效率低下。复制简单(非嵌套)列表就像cpy = myList[:] 一样简单。您可以通过myList[:k]+myList[k+1:] 忽略元素索引k 关注极端情况;但这也会为您创建一个列表。
  • 删除一个元素也很昂贵,所以副本不要太费劲......

标签: python list function


【解决方案1】:

您可以为此使用itertools.combinations

import itertools

for sublist in itertools.combinations([a, b, c, d, e], 4):
    # 4 is the number of elements in each sublist.
    # If you do not know the length of the input list, use len() - 1
    doSomething(sublist)

这将使sublist 成为一个元组。如果你需要它是一个列表,你可以在传递给doSomething()之前调用list()

如果您关心doSomething() 调用的完成顺序,您将需要颠倒迭代顺序,以便从删除第一个元素而不是最后一个元素开始:

for sublist in reversed(list(itertools.combinations([a, b, c, d, e], 4))):
    doSomething(sublist)

这样效率较低,因为必须预先生成所有子列表,而不是一次生成一个。 cmets 中的 mgilson 建议反转输入列表,然后反转每个子列表,这样应该会更高效,但代码可能更难阅读。

【讨论】:

  • 我也想过提出这个建议。我很想知道这种方法和天真的方法之间的时间比较。
  • 您能否反转输入 ([e, d, c, b, a]),然后反转子列表,然后再将它们传递给 doSomething?这将阻止获得 all 列表。
【解决方案2】:

通常,循环遍历索引是一个坏主意 - 但在这种情况下,您似乎想(迭代地)删除给定索引处的元素,因此循环遍历索引实际上似乎适合一次。

您可以为此目的使用list.pop,但事实证明,对于循环的每一轮,这将是一个额外的 O(N) 操作(一次用于复制列表,一次用于删除第 i 个元素)。我们可以通过在复制时删除元素来做不同的事情......

for i in range(len(lst)):
    new_list = [x for j, x in enumerate(lst) if j != i]
    doSomething(new_list)

但请注意,不能保证这会比天真的方法更快:

for i in range(len(lst)):
    new_list = lst[:]  # lst.copy() in python3.x
    new_list.pop(i)
    doSomething(new_list)

天真的方法的优点是,需要在 .pop 中完成的任何索引都被推送到 C 代码,这通常比进行 python 比较要快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-15
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多