【问题标题】:getting list without k'th element efficiently and non-destructively有效且非破坏性地获取没有第 k 个元素的列表
【发布时间】:2011-01-09 16:35:18
【问题描述】:

我在 python 中有一个列表,我想遍历它,并有选择地构造一个包含除当前第 k 个元素之外的所有元素的列表。我可以这样做的一种方法是:

l = [('a', 1), ('b', 2), ('c', 3)]
for num, elt in enumerate(l):
  # construct list without current element
  l_without_num = copy.deepcopy(l)
  l_without_num.remove(elt)

但这似乎效率低下且不优雅。有简单的方法吗?请注意,我基本上想获得不包括当前元素的原始列表的一部分。似乎应该有更简单的方法来做到这一点。

感谢您的帮助。

【问题讨论】:

  • 我想到的另一种方法如下: # 假设 k 是要排除的元素 filter(lambda x: x[0] != k, l) 这是可敬的吗?有更好的方法吗?
  • 你能解释一下预期的结果是什么吗? "NameError: name 'copy' 未定义"
  • 我不清楚这个操作的结果应该是什么。您发布的实现构造但不使用原始列表的 3 个不同副本,缺少三个不同的元素。你能阐明你的目标吗?

标签: python list copying


【解决方案1】:

在集合上使用差分运算符:

list(set(l).difference([l[k]])

l=[('a', 1), ('b', 2), ('c', 3)]
list(set(l).difference([l[1]]))
[('a', 1), ('c', 3)]

【讨论】:

    【解决方案2】:
    #!/bin/bash
    `python -c "'\n'.join(mylist[:])" 2>NULL | sed '/mybadelement/d'`
    

    哈哈

    【讨论】:

      【解决方案3】:

      可能不是最有效的,但我的函数式程序员可能会写这个。

      import operator
      from itertools import *
      def inits(list):
          for i in range(0, len(list)):
              yield list[:i]
      def tails(list):
          for i in range(0, len(list)):
              yield list[i+1:]
      def withouts(list):
          return imap(operator.add, inits(list), tails(list))
      
      for elt, without in izip(l, withouts(l)):
          ...
      

      import functools, operator
      for elt in l:
          without = filter(functools.partial(operator.ne, elt), l)
      

      我不认为这是正确的做法,但它很短。 :-)

      【讨论】:

      • 也许里面应该有一个ifilter? :)
      • 投反对票的人会评论为什么吗?第一个解决方案在结果和算法复杂性方面与领先的答案相当。
      【解决方案4】:
      new = [l[i] for i in range(len(l)) if i != k]
      

      【讨论】:

        【解决方案5】:
        l=[('a', 1), ('b', 2), ('c', 3)]
        k=1
        l_without_num=l[:]   # or list(l) if you prefer
        l_without_num.pop(k)
        

        【讨论】:

          【解决方案6】:

          如果您能详细说明您想如何使用它,将会有所帮助。但是你可以对列表理解做同样的事情。

          l = [('a', 1), ('b', 2), ('c', 3)]
          k = 1
          l_without_num = [elt for num, elt in enumerate(l) if not num == k]
          

          如果您不必将其存储在 l_without_num 中,这也可以更高效地进行迭代。

          【讨论】:

            【解决方案7】:
            l = [('a', 1), ('b', 2), ('c', 3)]
            k = 1
            l_without_num = l[:k] + l[(k + 1):]
            

            这是你想要的吗?

            【讨论】:

            • +1,绝对是最好的方法!既然可以切片和连接,为什么还要迭代?-)
            • 这对所有 k
            猜你喜欢
            • 1970-01-01
            • 2011-01-15
            • 2014-10-26
            • 1970-01-01
            • 1970-01-01
            • 2013-12-17
            • 1970-01-01
            • 2023-03-24
            • 2016-04-16
            相关资源
            最近更新 更多