拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Python列表方法append和extend的终极对比

问此问题的答案乃社区的付出, 编辑现有的答案用以改良这篇文章, 它当下不接纳新的答案或者互动。列表方法 () 和 () 有什么区别答1:包揽那个全网唯一的, 那种一条龙全面的, 外包任务、远程工作、创意产品分享以及订阅服务的提供!在列表末尾附加一个指定对象 x [1, 2, 3] x.append([4, 5]) print(x) [1, 2, 3, [4, 5]]通过附加来自指定迭代的元素来扩展列表 x [1, 2, 3] x.extend([4, 5]) print(x) [1, 2, 3, 4, 5]仅使用加法运算符, 在上面的示例里, 是 x x , 那么和它有什么区别呢?实际上, 存在着一项颇为显著的差异, 那便是 x 会给您赋予一个全新的列表用于分配给 x, 然而 x.() 却对原本的列表造成了改变, 关于此点我会在下面的答案里依照详细情形予以阐述。 Rohan 但它与 x 相同。运用的时候, 所用到的关键字是这个。要是您试着去运用它, 并且进行传入操作, 那么它就会把那个key, 而非整个哈希, 附加到数组的末尾处。Rohan, 存在这样一种情况, x等于x加上某个值时, 其时间复杂度是O(len(x)加上len()), 这里面, 某个值的时间复杂度是O(len())。答2:洞察每一个产品背后的需求与收益从而捕获灵感把元素增添至列表里头, 把首个列表跟另一个列表或者可迭代物体进行连接。 xs [A, B] xs [A, B] xs.append(D) xs [A, B, D] xs.append([E, F]) xs [A, B, D, [E, F]] xs.insert(2, C) xs [A, B, C, D, [E, F]] xs.extend([G, H]) xs [A, B, C, D, [E, F], G, H]答3:洞察每一个产品背后的需求与收益从而捕获灵感列表方法追加和扩展有什么区别把那个参数当作单独的一个元素, 增添到列表的最后面。列表自身的长度从而会增加一个。其参数进行迭代, 把每个元素增添至列表里, 使列表实现扩展。不管可迭代参数含几个元素, 列表的长度都会得以增加。附加list. 方法将一个对象附加到列表的末尾。my_list.append(object)不管对象究竟是啥, 不管是那个数字、那个字符串、又一个列表, 亦或是别样的对象, 它皆会当作列表中的单个条目添到末尾。 my_list [foo, bar] my_list.append(baz) my_list [foo, bar, baz]所以, 请记住, 列表, 它之为一个对象。要是您去把另一个列表附加于这个列表之中, 那么第一个列表, 会成为处于列表末尾位置的单个对象, 而这, 或许并非是您所期望得到的结果: another_list [1, 2, 3] my_list.append(another_list) my_list [foo, bar, baz, [1, 2, 3]] #^^^^^^^^^--- single item at the end of the list.延长list. 方法通过附加来自可迭代对象的元素来扩展列表my_list.extend(iterable)因此通过扩展可迭代的每个元素都被附加到列表中。例如 my_list [foo, bar] another_list [1, 2, 3] my_list.extend(another_list) my_list [foo, bar, 1, 2, 3]要记好, 字符串具备可迭代性, 所以要是你运用字符串去扩展列表, 那么在迭代字符串这个操作举动当中, 将会针对每一个字符进行附加行为这或许并非是你内心所期望达成的状况: my_list.extend(baz) my_list [foo, bar, 1, 2, 3, b, a, z]运算符重载add () 和 iadd ()先是在内存里创建第三个列表, 所以您能够返回它的结果, 然而它规定第二个可迭代对象乃是一个列表。对列表进行 操作, 会就地修改列表, 它属于就地运算符且列表是可变对象, 就像我们所看到的那样, 所以它不会创建新列表。它在特定情况时的工作效果类似, 因为第二个操作对象可以是任何类型的。别将两者混淆, 等于加上并不等同于加上成为, 它为您给予分配给的全新列表。时间复杂度追加有 () time , O(1)。具有时间复杂度 O(k)。对该遍历的多次调用, 会致使复杂性增加, 会让其与另一个相比等效, 且鉴于其迭代是在C里达成的, 所以要是您计划把可迭代的连续项附加于列表, 那它始终都会来得更快。关于“摊销”——来自 list /* This over-allocates proportional to the list size, making room * for additional growth. The over-allocation is mild, but is * enough to give linear-time amortized behavior over a long * sequence of appends() in the presence of a poorly-performing * system realloc().如下这般表明, 针对那内存予以重新分配, 其好处是我们在预先之时就已获取到了的, 并且这好处所得大于所需, 然而, 在紧接着到来的边际重新分配环节里, 我们极有可能要为此付出更为高昂的代价。所有那些追加起来的总时间, 处于 O(n)的情况之下呈现为线性状态, 而且, 每一次追加分配所涉及的时间都转变成为了 O(1)。表现您或许说不定会想晓得啥会是更具高效性的, 鉴于其能够被用来达成跟那一样的成果。以下所提及的函数完成的是相同方面的事儿:def append(alist, iterable): for item in iterable: alist.append(item) def extend(alist, iterable): alist.extend(iterable)所以让我们给他们计时import timeit min(timeit.repeat(lambda: append([], abcdefghijklmnopqrstuvwxyz))) 2.867846965789795 min(timeit.repeat(lambda: extend([], abcdefghijklmnopqrstuvwxyz))) 0.8060121536254883解决对时间的评论一位评论者说完美的答案我只是错过了比较只添加一个元素的时间去做在语义层面是正确无误的事情, 要是您打算于一个能够进行迭代的对象范围以内添加尽所有的相应元素, 那就使用那个, 要是您仅仅只是想要添加单一的一个元素, 那就使用这个。好的让我们创建一个实验看看它是如何及时完成的def append_one(a_list, element): a_list.append(element) def extend_one(a_list, element): creating a new list is semantically the most direct way to create an iterable to give to extend a_list.extend([element]) import timeit我们能够看到, 并且, 为了去使用扩展, 专门去创建一个可以进行迭代的对象, 这属于轻微程度的时间方面的浪费。 min(timeit.repeat(lambda: append_one([], 0))) 0.2082819009956438 min(timeit.repeat(lambda: extend_one([], 0))) 0.2397019260097295我们从中知晓这事, 当我们仅有一个元素去实施附加动作时, 运用它不存在任何益处。另外, 这些时间并非那般重要。我仅仅是向他们表明, 于其中, 做语义无误的事情乃是通过正确的方式去做事™。能够想象得出, 您大概有可能会于两个能够进行比较对照的这种操作之上检测试验时序从而获取令人模棱两可或者相反相悖的结果。仅仅专心致志地去做在语义层面上属于正确无误之事。结论我们能看到, 在语义方面更为清晰, 而且它能够比, 运行得速度更快, 当您准备把迭代之中的每个元素附加于列表的时候。如果您只有一个元素不在迭代中要添加到列表中请使用 。针对Aaron Hall, 有关于计时算法的一条小评论。此评论指出, 可能会返回那种“稍微错误”的时间, 这是由于还牵扯到列表的创建。要是您想更为严格对待, 那么最好把项目创建成变量, 比如设ex1为0, 设ex2为某个值, 然后传递这些变量。的确是堪称完美的答案, l1加上l2与l1括号里l2的性能究竟怎样呢?Jean -.: l1加上l2和l1对l2进行某种操作之后执行相同的代码在.c中的函数, 唯一明显的差别是: 一、进行加法操作时会重新分配l1对于列表而言, 不过重新分配支持的是可变类型, 之后并不是同一个对象, 要是l1实际上属于不可变对象的属性举例来说, t等于一个元组、t加上lst会失败, 而t对lst进行操作会成功标点符号。2. 首先, l1 l2 运用专用字节码这事, 然后, l1.(l2) 使用通用方法调度这就致使 相比之下更快些。关于 这个操作, 必须重新分配 l1 的这一事实, 确实意味着, 在某些情形下, 其较慢调度这一部分或者全部, 是通过不分配回左侧来进行弥补的。比如说, 要是 list 是一个对象的属性, 那么 self.l1 l2 和 self.l1.(l2) 在我的 3.6 安装上都有着相同的性能, 仅仅是由于实际操作更类似于 self.l1 self.l1.(l2), 这就意味着它必须执行适度昂贵, 而 self.l1.(l2) 则没有这种必要。在本地测试里的简便比较: 针对一个本地变量所以 仅是运用 , 它极为便宜, 这里要加入的值是一个已有的 list , 该 list 有一个项目, 反复操作 1000 次, 平均用时约 33 ns , 然而 用时 78 ns , 相差 45 ns。要是 l1 是全局的需更昂贵的, 那么差异缩减至 17 ns。假如l1实际上是local.l1这是需要更昂贵代价的那种情况, 那么在 和 之间不存在有意义的区别二者时间大致是相同的有时候 会体现出优势得以胜出。答4:周刊, 不定时, 分享成功产品案例, 以学习他们怎样把自身的副业成功组建起来。附加一个元素。 附加元素列表。请注意如果您传递一个列表来追加它仍然会添加一个元素 a [1, 2, 3] a.append([4, 5, 6]) a [1, 2, 3, [4, 5, 6]]高效搞钱一站式跟进超10任务平台外包需求答5:高效搞钱一站式跟进超10任务平台外包需求追加与扩展使用 您可以附加一个将扩展列表的元素 a [1,2] a.append(3) a [1,2,3]如果你有着想要去扩展多个元素这样的想法, 你应当予以使用, 鉴于你仅仅能够去附加一个元素或者是一个元素列表 a.append([4,5]) a [1,2,3,[4,5]]这样你就得到一个嵌套列表而不是使用您可以像这样扩展单个元素 a [1,2] a.extend([3]) a [1,2,3]或者, 不同于追加, 一次扩展再多些元素, 且不把列表嵌套进原始列表内这便是称作扩展的缘由。 a.extend([4,5,6]) a [1,2,3,4,5,6]使用两种方法添加一个元素和 都可以将一个元素添加到列表的末尾尽管 更简单。追加 1 个元素 x [1,2] x.append(3) x [1,2,3]扩展一个元素 x [1,2] x.extend([3]) x [1,2,3]添加更多元素…具有不同的结果要是您针对多个元素予以使用, 那么就一定要把元素列表作为参数进行传递, 如此您便会获取到一个列表 x [1,2] x.append([3,4]) x [1,2,[3,4]]相反, 您传递, 将一个列表当作参数, 然而您会得到, 一个包含新元素的列表, 且这些新元素未嵌套在旧元素之中 , 这是使用之后会出现的情况。 z [1,2] z.extend([3,4]) z [1,2,3,4]因此, 针对诸多元素, 您会运用 去获取涵盖更多项目的列表。然而, 追加列表并非往列表里增添更多元素, 而是添加一个嵌套列表的元素, 您能够在代码输出里清晰地瞧见。答6:洞察每一个产品背后的需求与收益从而捕获灵感以下两个片段在语义上是等效的for item in iterator: a_list.append(item)a_list.extend(iterator)后者可能会更快因为循环是用 C 实现的。在我的机器上面, 扩展比在循环当中附加快大概4倍, 也就是16us相较于4us, 用于100个零循环标点符号。() 可能预分配而 () 可能没有。: 为求完整, 有时, () 没办法明智地预先去分配, 因某些迭代未实现 (), 不过像你这般, 要是它没实现, 我会觉惊讶, 别去尝试。如指明于Aarons中的, 一些性能提升源自于在纯C里而非在中执行迭代部分。答7:与一起探索全球自由职业机会–() 方法将单个项目添加到列表的末尾。x [1, 2, 3] x.append([4, 5]) x.append(abc) print(x) # gives you [1, 2, 3, [4, 5], abc]有种方法, 采纳一个参数, 还有一个列表, 会把参数里的每一个项目逐个附加给原本的列表。列表是通过类方式来实现的。“创建”那个列表, 实际上就是让一个类实例化。所以呢, 列表拥有针对它自身去开展操作的方法。x [1, 2, 3] x.extend([4, 5]) x.extend(abc) print(x) # gives you [1, 2, 3, 4, 5, a, b, c]来自 Dive Into 。仅使用6来进行扩展这件事您是不可以做的, 原因在于它没办法进行迭代。您所给出示例里的第二个输出是存在错误情况的。“abc”被当作单个元素添加进去了, 这是由于您把它当成是具有一个元素的。abc的列表传递给 1, 2, 3, 4, 5, abc要让示例有着正确的输出, 那就需要把abc行变更为: x.((abc)), 并且要将x.(6)给删除, 或者是把它更改为x.()。“() 方法接受一个参数一个列表”也是错误的答8:聚合了全球外包任务平台中数量超过10个以上的需求, 找寻外包任务以及机会, 变得简单且高效了。您可以使用“”返回扩展而不是就地扩展。l1range(10) l1[11] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11] l2range(10,1,-1) l1l2 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2]和 相似, 是为进行就地行为而设, 不过跟 存在些许差异。 同 和 的最大差别之一在于, 当它应用于函数范围的时候, 可查看这篇博客文章。使用“”返回扩展对时间复杂度有影响吗有关详细信息请参阅此答案/a//我不明白这是如何回答问题的答9:一个称得上优秀的自由职业者, 得具备对需求敏感的能力, 还得拥有能够精准捕获需求的本事, 并且提供了这般的机会。() - 通过将对象添加到列表来更新列表。x [20] # List passed to the append(object) method is treated as a single object. x.append([21, 22, 23]) # Hence the resultant list length will be 2 print(x) -- [20, [21, 22, 23]](list) - 本质上连接两个列表。x [20] # The parameter passed to extend(list) method is treated as a list. # Eventually it is two lists being concatenated. x.extend([21, 22, 23]) # Here the resultant lists length is 4 print(x) [20, 21, 22, 23]答10:洞察每一个产品背后的需求与收益从而捕获灵感这相当于使用 运算符的 和 x [1,2,3] x [1, 2, 3] x x [4,5,6] # Extend x [1, 2, 3, 4, 5, 6] x x [[7,8]] # Append x [1, 2, 3, 4, 5, 6, [7, 8]]答11:高效搞钱一站式跟进超10任务平台外包需求能够跟迭代器参数一块儿运用, 这是个示例, 您期望通过这般路数从列表的列表里构建出一个列表。list2d [[1,2,3],[4,5,6], [7], [8,9]]你要 [1, 2, 3, 4, 5, 6, 7, 8, 9]对于执行此操作, 您能够运用.chain.()。此一办法所产生的输出是一个迭代器。它的达成跟……等价。def from_iterable(iterables): # chain.from_iterable([ABC, DEF]) -- A B C D E F for it in iterables: for element in it: yield element回到我们的例子我们可以做import itertools list2d [[1,2,3],[4,5,6], [7], [8,9]] merged list(itertools.chain.from_iterable(list2d))并获得通缉名单。下面是如何等效地将 () 与迭代器参数一起使用merged [] merged.extend(itertools.chain.from_iterable(list2d)) print(merged) [1, 2, 3, 4, 5, 6, 7, 8, 9]
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门