【问题标题】:Modify a large list without any loops in python在python中修改一个没有任何循环的大列表
【发布时间】:2011-12-08 20:10:07
【问题描述】:

我的清单是:

a=[1,2,3,4]

现在我希望我的列表是:

a=[-1,-2,-3,-4]

如何在不使用任何循环的情况下以这种方式更改我的列表?

更新:这可能是一个大列表,大约 10000 个元素。

【问题讨论】:

  • 有什么特别的理由不循环吗?
  • 由于时间限制.. 循环需要大量时间。我必须修改包含多达 10000 个整数的列表
  • 为什么您认为超过 10000 个整数的单个循环是您的瓶颈问题?这真的不会花很长时间。
  • 请注意,使用“map”和“lambda”的答案会比循环慢。只是“不循环”本身不会使您的代码更快。
  • 也许你应该想办法不否定,所以你能说出你为什么要否定,在这种情况下为什么循环更慢?

标签: python list


【解决方案1】:

使用 Python 的 map 功能

a[:] = map(lambda x: -x, a)

以下是上述链接中对地图功能的描述:

ma​​p(函数,可迭代,...)
将函数应用于可迭代的每个项目并返回 结果。如果传递了额外的可迭代参数,函数必须 接受那么多参数并应用于所有项目 并行迭代。如果一个可迭代的比另一个短,它是 假设用 None 项目扩展。如果函数为无,则 假设恒等函数;如果有多个参数,map() 返回由包含相应项的元组组成的列表 来自所有可迭代对象(一种转置操作)。可迭代的 参数可以是一个序列或任何可迭代的对象;结果是 总是一个列表。

【讨论】:

  • 这不会修改现有的列表,它会将变量a 替换为答案被否定的新列表。 (当然这对 OP 来说可能是可以接受的,但这是一个细微的差别。)
  • 它是否比循环或列表理解快得多?
  • 如果不是使用a = ... 分配,而是使用a[:] = ...,那么这通过执行切片分配来更改列表。然后对该列表的其他引用将看到否定值。
  • @PaulMcGuire 谢谢我不知道,相应地更新了我的答案。
  • Alex Martelli 在他对这个问题的回答中向我展示了这一点:stackoverflow.com/questions/1207406/…
【解决方案2】:

来自 ipython 的一些快速而肮脏的基准测试

In [1]: a=range(10000)

In [2]: import numpy 

In [3]: timeit [-i for i in a]
1000 loops, best of 3: 576 us per loop

In [4]: timeit map(lambda i:-i, a)
1000 loops, best of 3: 1.68 ms per loop

In [5]: timeit list(-1*numpy.array(a))
100 loops, best of 3: 2.53 ms per loop

请注意,如果 a 可以是一个 numpy 数组,则您无需在转换上浪费时间

In [6]: a = numpy.array(a)

In [7]: timeit -- -a
100000 loops, best of 3: 15.4 us per loop

【讨论】:

    【解决方案3】:

    你可以使用 numpy 库:

    list(-1*numpy.array(a))
    

    【讨论】:

    • 不幸的是,在 Python 和 numpy 之间转换的开销使得它不适合加速这样的单次操作
    【解决方案4】:
    import operator
    a = map(operator.neg, a)
    

    【讨论】:

    • 请注意,与使用 map 的其他答案不同,此答案可能比显式循环更快。其他map 答案都使用lambda,这会使它们变慢。
    【解决方案5】:

    这取决于你的意思是没有任何循环。如果您只想避免像

    这样的显式循环
    a = [ -x for x in a ]
    

    你可以使用 map 函数,它会为你循环。

    a = map( lambda x:-x, a)
    

    【讨论】:

      【解决方案6】:

      你不能没有循环,但你可以隐藏事实。

      map(lambda x: -x, a)
      

      【讨论】:

        【解决方案7】:

        不知道为什么不需要循环的确切原因并且知道没有其他有效的方法来否定一个列表是我的超快速解决方案(我不知道上下文,所以这可能不起作用)

        class nlist(object):
            def __init__(self, l):
                self._list = l
        
            def __getitem__(self, key):
                return -self._list[key]
        
            def __iter__(self):
                for i in self._list:
                    yield -i
        
        
        nl = nlist([1,2,3,4])
        for i in nl:
            print i
        

        【讨论】:

          【解决方案8】:
          a = [-a[0], -a[1], -a[2], -a[3]]
          

          现在的问题是,这仅在 a 正好有 4 个项目时才有效。概括为不同数量的项目......这就是循环的用途。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-11
            • 1970-01-01
            • 2011-09-11
            • 1970-01-01
            • 2015-05-07
            • 2019-04-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多