【问题标题】:pop/remove items out of a python tuple从 python 元组中弹出/删除项目
【发布时间】:2014-02-10 16:36:05
【问题描述】:

我不确定我是否可以说清楚,但会尝试。

我在 python 中有一个元组,如下所示(见下面的代码)。在处理过程中,我维护了一个计数器(我们称之为“n”)和“pop”满足特定条件的项目。

当然,一旦我弹出第一个项目,编号就会出错,我怎样才能更优雅地做我想做的事,同时只动态删除元组的某些条目?

for x in tupleX:
  n=0
  if (condition):
     tupleX.pop(n)
  n=n+1

【问题讨论】:

  • tuples 是不可变的,并且没有 pop 方法。你真的在说list吗?
  • @DSM 在 6 年前是正确的,但 Python 3 允许对元组进行切片,因此可以有效地弹出。

标签: python tuples


【解决方案1】:

正如DSM 提到的,tuple 是不可变的,但即使对于列表,更优雅的解决方案是使用filter

tupleX = filter(str.isdigit, tupleX)

或者,如果condition 不是函数,则使用推导:

tupleX = [x for x in tupleX if x > 5]

如果您确实需要将 tupleX 作为元组,请使用生成器表达式并将其传递给 tuple

tupleX = tuple(x for x in tupleX if condition)

【讨论】:

  • 供他人参考,生成器表达式在速度方面是最优的。
  • @Alecg_O:您能否为该声明提供基准?事实上,如果condition 是一个(未应用的)C 函数(如我提供的示例中),filter 通常更快;生成器表达式必须执行一些 python 字节码,但不需要创建调用框架(也与我的列表理解示例一样)。
  • 根据docs,过滤器和生成器解决方案在功能上是相同的 - 都返回原始过滤条件的迭代,并且根据这个定义,两者都是常数时间。但是,假设 OP 需要一个元组作为输出,则不同之处在于转换回来。为了证明:从生成器中取出 tuple() ,它们都会立即返回,但是 tuple() 过滤器需要更长的时间,与 tupleX 的大小成正比。
  • 有趣的旁注:我在寻找从元组中“删除”单个项目的最有效方法时遇到了这篇文章。虽然这些都是很好的解决方案,但具有讽刺意味的是 "x = list(x); x.remove(); x = tuple(x)" 比其中任何一个都快:P
【解决方案2】:

是的,我们可以做到。 先将元组转换成列表,然后删除列表中的元素,再转换回元组。

演示:

my_tuple = (10, 20, 30, 40, 50)

# converting the tuple to the list
my_list = list(my_tuple)
print my_list  # output: [10, 20, 30, 40, 50]

# Here i wanna delete second element "20"
my_list.pop(1) # output: [10, 30, 40, 50]
# As you aware that pop(1) indicates second position

# Here i wanna remove the element "50"
my_list.remove(50) # output: [10, 30, 40]

# again converting the my_list back to my_tuple
my_tuple = tuple(my_list)


print my_tuple # output: (10, 30, 40)

谢谢

【讨论】:

  • 这是一个糟糕的方法。您将分配一个列表,执行一个操作,然后分配另一个元组。更快更优雅的方法是创建一个没有元素的新元组
【解决方案3】:

好吧,我想出了一个粗略的方法。

当条件满足时,我将“n”值存储在 for 循环中(我们称之为 delList),然后执行以下操作:

    for ii in sorted(delList, reverse=True):
    tupleX.pop(ii)

也欢迎任何其他建议。

【讨论】:

    【解决方案4】:

    也许你想要字典?

    d = dict( (i,value) for i,value in enumerate(tple))
    while d:
        bla bla bla
        del b[x]
    

    【讨论】:

    • 不,我必须使用一个元组,因为它是由一个外部函数提供给我的,我无法编辑具有太多依赖关系的旧分层代码。
    • 谢谢,我会试试这个——比我的方法更优雅。
    【解决方案5】:

    Python 3 中,这不再是一个问题,而且您真的不想使用列表推导、强制、过滤器、函数或 lambdas 来处理类似的事情。

    随便用

    popped = unpopped[:-1]
    

    记住它是不可变的,所以如果你想改变它就必须重新分配值

    my_tuple = my_tuple[:-1]
    

    例子

    >>> foo= 3,5,2,4,78,2,1
    >>> foo
    (3, 5, 2, 4, 78, 2, 1)
    foo[:-1]
    (3, 5, 2, 4, 78, 2)
    

    如果你想要弹出的值,,

    >>> foo= 3,5,2,4,78,2,1
    >>> foo
    (3, 5, 2, 4, 78, 2, 1)
    >>> foo, bit = foo[:-1], foo[-1]
    >>> bit
    1
    >>> foo
    (3, 5, 2, 4, 78, 2)
    

    或者,使用从后面开始的元组的每个值...

    foo = 3,5,2,4,78,2,1
    for f in reversed(foo):
        print(f)  # 1; 2; 78; ...
    

    或者,用计数...

    foo = 3,5,2,4,78,2,1
    for f, i in enumerate(reversed(foo)):
        print(i, f)  # 0 1; 1 2; 2 78; ...
    

    或者,强制进入列表..

    bar = [*foo]
    #or 
    bar = list(foo)
    

    【讨论】:

      【解决方案6】:

      有一个简单但实​​用的解决方案。

      正如 DSM 所说,元组是不可变的,但我们知道列表是可变的。 因此,如果您将元组更改为列表,它将是可变的。然后您可以按条件删除项目,然后再次将类型更改为元组。就是这样。

      请看下面的代码:

      tuplex = list(tuplex)
      for x in tuplex:
        if (condition):
           tuplex.pop(tuplex.index(x))
      tuplex = tuple(tuplex)
      print(tuplex)
      

      例如,以下过程将从给定元组中删除所有偶数。

      tuplex = (1, 2, 3, 4, 5, 6, 7, 8, 9)
      tuplex = list(tuplex)
      for x in tuplex:
        if (x % 2 == 0):
           tuplex.pop(tuplex.index(x))
      tuplex = tuple(tuplex)
      print(tuplex)
      

      如果你测试最后一个元组的类型,你会发现它是一个元组。

      最后,如果你想像你一样定义一个索引计数器(即 n),你应该在循环之前初始化它,而不是在循环中。

      【讨论】:

        【解决方案7】:

        最好的解决方案是将元组应用于列表推导,但要提取一个 这个可以工作的项目:

        def pop_tuple(tuple, n): return tuple[:n]+tuple[n+1:], tuple[n]

        【讨论】:

          【解决方案8】:

          假设你有一个dict 以元组作为键,例如:labels = {(1,2,0): 'label_1'} 你可以修改元组键的元素如下:

          formatted_labels = {(elem[0],elem[1]):labels[elem] for elem in labels}
          

          在这里,我们忽略了最后的元素。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-10-19
            • 2016-04-22
            • 1970-01-01
            • 1970-01-01
            • 2022-12-23
            • 1970-01-01
            相关资源
            最近更新 更多