简体   繁体   English

Python 3 中的 collections.deque 是否有类似列表理解的东西?

[英]Is there something like list comprehensions for collections.deque in Python 3?

Question问题

Is there a way to do something like有没有办法做类似的事情

some_list = [int(x) for x in input().split()]

but return a collections.deque object instead of a list?但返回collections.deque object 而不是列表? In particular, I'm attempting to avoid creating a list and converting it with deque(some_list) since that adds a factor of O(n) to the time complexity as demonstrated here and explained here .特别是,我试图避免创建一个列表并使用deque(some_list)对其进行转换,因为这会为时间复杂度增加一个 O(n) 因子,如此处所示并此处解释。

Context语境

I'm working on a practice HackerRank problem for fun (but will avoid sharing it here to avoid the risk of people spoiling the fun of finding an answer).我正在研究一个练习 HackerRank 的问题(但会避免在这里分享,以免人们破坏寻找答案的乐趣)。 Consequently, I won't be giving an example output since it would only make sense within the full context of the problem.因此,我不会给出示例output因为它只在问题的完整上下文中才有意义。 There are, however, some relevant things I can disclose that don't run the risk of spoilers.但是,我可以透露一些相关的事情,这些事情不会有剧透的风险。

Relevant stuff相关的东西

  1. I'm taking in very large lists/deques (up to 100k elements) via stdin.我正在通过标准输入接收非常大的列表/双端队列(最多 100k 个元素)。 They need to be converted to integers after (or while) being read in.它们需要在读入之后(或同时)转换为整数。

  2. Elements in the list/deque itself are between 1 and 2 31 .列表/双端队列本身的元素介于 1 和 2 31之间。

  3. I need to quickly compare and pop from both ends.我需要快速比较并从两端弹出。 There's no need to (a) look in the middle of the data, nor (b) sort it.无需(a)查看数据中间,也无需(b)对其进行排序。

  4. I'm restricted to using stdin to take in the data, but I will know the size of the list/deque ahead of time.我仅限于使用标准输入来接收数据,但我会提前知道列表/双端队列的大小。

  5. Fast runtime execution is desired, but I'm unfortunately restricted from using Numpy, Pandas, and Numba to help.需要快速运行时执行,但不幸的是,我无法使用 Numpy、Pandas 和 Numba 来提供帮助。

My reasoning for thinking about deques and list comprehensions我思考双端队列和列表推导的理由

Because of (3) & (5), it seems like the deque object is the best way to go.由于 (3) 和 (5),似乎deque object 是 go 的最佳方式。 Because of (1) & (5), I'd like to convert the input into integers right away which is why list comprehensions came to mind.由于 (1) 和 (5),我想立即将输入转换为整数,这就是为什么会想到列表推导的原因。

Example input示例输入

The 1st line, n , tells me how many integers will be on the 2nd line.第一行n告诉我第二行有多少个整数。

4
5 2 42 199
Example code snippet to read in input读取输入的示例代码片段

The following code works for reading in the input while converting it to integers:以下代码用于在将输入转换为整数时读取输入:

n = int(input())
wish_this_was_a_deque = [int(x) for x in input().split()]

But as mentioned before, I'd like to immediately convert the input into integers while also creating a deque and skipping the list entirely (for performance speed reasons).但如前所述,我想立即将输入转换为整数,同时创建一个deque并完全跳过列表(出于性能速度原因)。

Concluding remarks结束语

Perhaps I'm mistaken in thinking that immediately converting the string input from stdin into integers and storing them in a deque would be faster doing this:也许我错误地认为立即将字符串输入从标准输入转换为整数并将它们存储在deque中会更快:

from collections import deque
# Get input, split on spaces, covert to integers, append to some_big_list
some_big_list = [int(x) for x in input().split()]
# Convert some_big_list into a deque
some_big_deque = deque(some_big_list)

If so, please feel free to correct this misconception even if there is a way to do a "deque comprehension".如果是这样,即使有办法进行“双端队列理解”,也请随时纠正这种误解。

In any case, I'm still interested if a "deque comprehension" is possible.无论如何,如果“双端队列理解”是可能的,我仍然很感兴趣。

Python offers a few types of comprehensions, but the most general form is the generator comprehension. Python 提供了几种类型的推导,但最通用的形式是生成器推导。 When you write当你写

[int(x) for x in input().split()]

This produces a list immediately.这会立即生成一个列表。 But without brackets但是没有括号

int(x) for x in input().split()

this is a generator comprehension .这是一个生成器理解 It produces a lazy iterable that, when evaluated, will produce the values.它产生一个惰性迭代器,在评估时将产生值。 It's as though we had written就好像我们写过

def my_generator():
  for x in input().split():
    yield int(x)

my_generator()

but much, much shorter.但要短得多。 Now, the reason this is useful is that deque , like many built-in Python collections, takes an arbitrary iterable as its constructor argument.现在,这很有用的原因是deque像许多内置的 Python collections 一样,将任意迭代作为其构造函数参数。 And a generator is a type of iterable.生成器是一种可迭代的。 So to get rid of the intermediate list, take your list comprehension所以要摆脱中间列表,把你的列表理解

some_big_deque = deque([int(x) for x in input().split()])

and remove the brackets并删除括号

some_big_deque = deque(int(x) for x in input().split()) # Look, Ma, no brackets!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM